Loading services/surfaceflinger/DisplayHardware/HWC2.cpp +0 −182 Original line number Diff line number Diff line Loading @@ -42,8 +42,6 @@ using android::HdrMetadata; using android::Rect; using android::Region; using android::sp; using android::hardware::Return; using android::hardware::Void; namespace HWC2 { Loading @@ -60,188 +58,8 @@ inline bool hasMetadataKey(const std::set<Hwc2::PerFrameMetadataKey>& keys, return keys.find(key) != keys.end(); } class ComposerCallbackBridge : public Hwc2::IComposerCallback { public: ComposerCallbackBridge(ComposerCallback* callback, int32_t sequenceId, bool vsyncSwitchingSupported) : mCallback(callback), mSequenceId(sequenceId), mVsyncSwitchingSupported(vsyncSwitchingSupported) {} Return<void> onHotplug(Hwc2::Display display, IComposerCallback::Connection conn) override { HWC2::Connection connection = static_cast<HWC2::Connection>(conn); mCallback->onHotplugReceived(mSequenceId, display, connection); return Void(); } Return<void> onRefresh(Hwc2::Display display) override { mCallback->onRefreshReceived(mSequenceId, display); return Void(); } Return<void> onVsync(Hwc2::Display display, int64_t timestamp) override { if (!mVsyncSwitchingSupported) { mCallback->onVsyncReceived(mSequenceId, display, timestamp, std::nullopt); } else { ALOGW("Unexpected onVsync callback on composer >= 2.4, ignoring."); } return Void(); } Return<void> onVsync_2_4(Hwc2::Display display, int64_t timestamp, Hwc2::VsyncPeriodNanos vsyncPeriodNanos) override { if (mVsyncSwitchingSupported) { // TODO(b/140201379): use vsyncPeriodNanos in the new DispSync mCallback->onVsyncReceived(mSequenceId, display, timestamp, std::make_optional(vsyncPeriodNanos)); } else { ALOGW("Unexpected onVsync_2_4 callback on composer <= 2.3, ignoring."); } return Void(); } Return<void> onVsyncPeriodTimingChanged( Hwc2::Display display, const Hwc2::VsyncPeriodChangeTimeline& updatedTimeline) override { hwc_vsync_period_change_timeline_t timeline; timeline.newVsyncAppliedTimeNanos = updatedTimeline.newVsyncAppliedTimeNanos; timeline.refreshRequired = updatedTimeline.refreshRequired; timeline.refreshTimeNanos = updatedTimeline.refreshTimeNanos; mCallback->onVsyncPeriodTimingChangedReceived(mSequenceId, display, timeline); return Void(); } private: ComposerCallback* mCallback; int32_t mSequenceId; const bool mVsyncSwitchingSupported; }; } // namespace anonymous // Device methods Device::Device(std::unique_ptr<android::Hwc2::Composer> composer) : mComposer(std::move(composer)) { loadCapabilities(); } void Device::registerCallback(ComposerCallback* callback, int32_t sequenceId) { if (mRegisteredCallback) { ALOGW("Callback already registered. Ignored extra registration " "attempt."); return; } mRegisteredCallback = true; sp<ComposerCallbackBridge> callbackBridge( new ComposerCallbackBridge(callback, sequenceId, mComposer->isVsyncPeriodSwitchSupported())); mComposer->registerCallback(callbackBridge); } // Required by HWC2 device std::string Device::dump() const { return mComposer->dumpDebugInfo(); } uint32_t Device::getMaxVirtualDisplayCount() const { return mComposer->getMaxVirtualDisplayCount(); } Error Device::getDisplayIdentificationData(hwc2_display_t hwcDisplayId, uint8_t* outPort, std::vector<uint8_t>* outData) const { auto intError = mComposer->getDisplayIdentificationData(hwcDisplayId, outPort, outData); return static_cast<Error>(intError); } Error Device::createVirtualDisplay(uint32_t width, uint32_t height, PixelFormat* format, Display** outDisplay) { ALOGI("Creating virtual display"); hwc2_display_t displayId = 0; auto intError = mComposer->createVirtualDisplay(width, height, format, &displayId); auto error = static_cast<Error>(intError); if (error != Error::None) { return error; } auto display = std::make_unique<impl::Display>(*mComposer.get(), mCapabilities, displayId, DisplayType::Virtual); display->setConnected(true); *outDisplay = display.get(); mDisplays.emplace(displayId, std::move(display)); ALOGI("Created virtual display"); return Error::None; } void Device::destroyDisplay(hwc2_display_t displayId) { ALOGI("Destroying display %" PRIu64, displayId); mDisplays.erase(displayId); } void Device::onHotplug(hwc2_display_t displayId, Connection connection) { if (connection == Connection::Connected) { // If we get a hotplug connected event for a display we already have, // destroy the display and recreate it. This will force us to requery // the display params and recreate all layers on that display. auto oldDisplay = getDisplayById(displayId); if (oldDisplay != nullptr && oldDisplay->isConnected()) { ALOGI("Hotplug connecting an already connected display." " Clearing old display state."); } mDisplays.erase(displayId); auto newDisplay = std::make_unique<impl::Display>(*mComposer.get(), mCapabilities, displayId, DisplayType::Physical); newDisplay->setConnected(true); mDisplays.emplace(displayId, std::move(newDisplay)); } else if (connection == Connection::Disconnected) { // The display will later be destroyed by a call to // destroyDisplay(). For now we just mark it disconnected. auto display = getDisplayById(displayId); if (display) { display->setConnected(false); } else { ALOGW("Attempted to disconnect unknown display %" PRIu64, displayId); } } } // Other Device methods Display* Device::getDisplayById(hwc2_display_t id) { auto iter = mDisplays.find(id); return iter == mDisplays.end() ? nullptr : iter->second.get(); } // Device initialization methods void Device::loadCapabilities() { static_assert(sizeof(Capability) == sizeof(int32_t), "Capability size has changed"); auto capabilities = mComposer->getCapabilities(); for (auto capability : capabilities) { mCapabilities.emplace(static_cast<Capability>(capability)); } } Error Device::flushCommands() { return static_cast<Error>(mComposer->executeCommands()); } // Display methods Display::~Display() = default; Loading services/surfaceflinger/DisplayHardware/HWC2.h +0 −51 Original line number Diff line number Diff line Loading @@ -52,7 +52,6 @@ namespace android { namespace HWC2 { class Display; class Layer; using VsyncPeriodChangeConstraints = hwc_vsync_period_change_constraints_t; using VsyncPeriodChangeTimeline = hwc_vsync_period_change_timeline_t; Loading Loading @@ -81,56 +80,6 @@ class ComposerCallback { virtual ~ComposerCallback() = default; }; // C++ Wrapper around hwc2_device_t. Load all functions pointers // and handle callback registration. class Device { public: explicit Device(std::unique_ptr<android::Hwc2::Composer> composer); void registerCallback(ComposerCallback* callback, int32_t sequenceId); // Required by HWC2 std::string dump() const; const std::unordered_set<Capability>& getCapabilities() const { return mCapabilities; }; uint32_t getMaxVirtualDisplayCount() const; Error getDisplayIdentificationData(hwc2_display_t hwcDisplayId, uint8_t* outPort, std::vector<uint8_t>* outData) const; Error createVirtualDisplay(uint32_t width, uint32_t height, android::ui::PixelFormat* format, Display** outDisplay); void destroyDisplay(hwc2_display_t displayId); void onHotplug(hwc2_display_t displayId, Connection connection); // Other Device methods Display* getDisplayById(hwc2_display_t id); android::Hwc2::Composer* getComposer() { return mComposer.get(); } // We buffer most state changes and flush them implicitly with // Display::validate, Display::present, and Display::presentOrValidate. // This method provides an explicit way to flush state changes to HWC. Error flushCommands(); private: // Initialization methods void loadCapabilities(); // Member variables std::unique_ptr<android::Hwc2::Composer> mComposer; std::unordered_set<Capability> mCapabilities; std::unordered_map<hwc2_display_t, std::unique_ptr<Display>> mDisplays; bool mRegisteredCallback = false; }; // Convenience C++ class to access hwc2_device_t Display functions directly. class Display { public: Loading services/surfaceflinger/DisplayHardware/HWComposer.cpp +141 −30 Original line number Diff line number Diff line Loading @@ -65,14 +65,88 @@ #define RETURN_IF_HWC_ERROR(error, displayId, ...) \ RETURN_IF_HWC_ERROR_FOR(__FUNCTION__, error, displayId, __VA_ARGS__) namespace { using android::hardware::Return; using android::hardware::Void; class ComposerCallbackBridge : public android::Hwc2::IComposerCallback { public: ComposerCallbackBridge(HWC2::ComposerCallback* callback, int32_t sequenceId, bool vsyncSwitchingSupported) : mCallback(callback), mSequenceId(sequenceId), mVsyncSwitchingSupported(vsyncSwitchingSupported) {} android::hardware::Return<void> onHotplug( android::Hwc2::Display display, android::Hwc2::IComposerCallback::Connection conn) override { HWC2::Connection connection = static_cast<HWC2::Connection>(conn); mCallback->onHotplugReceived(mSequenceId, display, connection); return android::hardware::Void(); } android::hardware::Return<void> onRefresh(android::Hwc2::Display display) override { mCallback->onRefreshReceived(mSequenceId, display); return android::hardware::Void(); } android::hardware::Return<void> onVsync(android::Hwc2::Display display, int64_t timestamp) override { if (!mVsyncSwitchingSupported) { mCallback->onVsyncReceived(mSequenceId, display, timestamp, std::nullopt); } else { ALOGW("Unexpected onVsync callback on composer >= 2.4, ignoring."); } return android::hardware::Void(); } android::hardware::Return<void> onVsync_2_4( android::Hwc2::Display display, int64_t timestamp, android::Hwc2::VsyncPeriodNanos vsyncPeriodNanos) override { if (mVsyncSwitchingSupported) { // TODO(b/140201379): use vsyncPeriodNanos in the new DispSync mCallback->onVsyncReceived(mSequenceId, display, timestamp, std::make_optional(vsyncPeriodNanos)); } else { ALOGW("Unexpected onVsync_2_4 callback on composer <= 2.3, ignoring."); } return android::hardware::Void(); } android::hardware::Return<void> onVsyncPeriodTimingChanged( android::Hwc2::Display display, const android::Hwc2::VsyncPeriodChangeTimeline& updatedTimeline) override { hwc_vsync_period_change_timeline_t timeline; timeline.newVsyncAppliedTimeNanos = updatedTimeline.newVsyncAppliedTimeNanos; timeline.refreshRequired = updatedTimeline.refreshRequired; timeline.refreshTimeNanos = updatedTimeline.refreshTimeNanos; mCallback->onVsyncPeriodTimingChangedReceived(mSequenceId, display, timeline); return android::hardware::Void(); } private: HWC2::ComposerCallback* mCallback; const int32_t mSequenceId; const bool mVsyncSwitchingSupported; }; } // namespace namespace android { HWComposer::~HWComposer() = default; namespace impl { HWComposer::HWComposer(std::unique_ptr<Hwc2::Composer> composer) : mHwcDevice(std::make_unique<HWC2::Device>(std::move(composer))) {} HWComposer::HWComposer(std::unique_ptr<Hwc2::Composer> composer) : mComposer(std::move(composer)) { loadCapabilities(); } HWComposer::HWComposer(const std::string& composerServiceName) : mComposer(std::make_unique<Hwc2::impl::Composer>(composerServiceName)) { loadCapabilities(); } HWComposer::~HWComposer() { mDisplayData.clear(); Loading @@ -80,12 +154,21 @@ HWComposer::~HWComposer() { void HWComposer::registerCallback(HWC2::ComposerCallback* callback, int32_t sequenceId) { mHwcDevice->registerCallback(callback, sequenceId); if (mRegisteredCallback) { ALOGW("Callback already registered. Ignored extra registration attempt."); return; } mRegisteredCallback = true; sp<ComposerCallbackBridge> callbackBridge( new ComposerCallbackBridge(callback, sequenceId, mComposer->isVsyncPeriodSwitchSupported())); mComposer->registerCallback(callbackBridge); } bool HWComposer::getDisplayIdentificationData(hwc2_display_t hwcDisplayId, uint8_t* outPort, DisplayIdentificationData* outData) const { const auto error = mHwcDevice->getDisplayIdentificationData(hwcDisplayId, outPort, outData); const auto error = static_cast<HWC2::Error>( mComposer->getDisplayIdentificationData(hwcDisplayId, outPort, outData)); if (error != HWC2::Error::None) { if (error != HWC2::Error::Unsupported) { LOG_HWC_DISPLAY_ERROR(hwcDisplayId, to_string(error).c_str()); Loading @@ -95,9 +178,8 @@ bool HWComposer::getDisplayIdentificationData(hwc2_display_t hwcDisplayId, uint8 return true; } bool HWComposer::hasCapability(HWC2::Capability capability) const { return mHwcDevice->getCapabilities().count(capability) > 0; bool HWComposer::hasCapability(HWC2::Capability capability) const { return mCapabilities.count(capability) > 0; } bool HWComposer::hasDisplayCapability(const std::optional<DisplayId>& displayId, Loading Loading @@ -133,13 +215,33 @@ std::optional<DisplayIdentificationInfo> HWComposer::onHotplug(hwc2_display_t hw hwcDisplayId == mInternalHwcDisplayId ? "internal" : "external", to_string(info->id).c_str(), hwcDisplayId); mHwcDevice->onHotplug(hwcDisplayId, connection); // Disconnect is handled through HWComposer::disconnectDisplay via // SurfaceFlinger's onHotplugReceived callback handling if (connection == HWC2::Connection::Connected) { mDisplayData[info->id].hwcDisplay = mHwcDevice->getDisplayById(hwcDisplayId); auto& displayData = mDisplayData[info->id]; // If we get a hotplug connected event for a display we already have, // destroy the display and recreate it. This will force us to requery // the display params and recreate all layers on that display. if (displayData.hwcDisplay != nullptr && displayData.hwcDisplay->isConnected()) { ALOGI("Hotplug connecting an already connected display." " Clearing old display state."); } displayData.hwcDisplay.reset(); auto newDisplay = std::make_unique<HWC2::impl::Display>(*mComposer.get(), mCapabilities, hwcDisplayId, HWC2::DisplayType::Physical); newDisplay->setConnected(true); displayData.hwcDisplay = std::move(newDisplay); mPhysicalDisplayIdMap[hwcDisplayId] = info->id; } else if (connection == HWC2::Connection::Disconnected) { // The display will later be destroyed by a call to // destroyDisplay(). For now we just mark it disconnected. auto& displayData = mDisplayData[info->id]; if (displayData.hwcDisplay) { displayData.hwcDisplay->setConnected(false); } else { ALOGW("Attempted to disconnect unknown display %" PRIu64, hwcDisplayId); } // The cleanup of Disconnect is handled through HWComposer::disconnectDisplay // via SurfaceFlinger's onHotplugReceived callback handling } return info; Loading Loading @@ -197,14 +299,18 @@ std::optional<DisplayId> HWComposer::allocateVirtualDisplay(uint32_t width, uint height, SurfaceFlinger::maxVirtualDisplaySize); return {}; } HWC2::Display* display; auto error = mHwcDevice->createVirtualDisplay(width, height, format, &display); hwc2_display_t hwcDisplayId = 0; const auto error = static_cast<HWC2::Error>( mComposer->createVirtualDisplay(width, height, format, &hwcDisplayId)); if (error != HWC2::Error::None) { ALOGE("%s: Failed to create HWC virtual display", __FUNCTION__); return {}; } auto display = std::make_unique<HWC2::impl::Display>(*mComposer.get(), mCapabilities, hwcDisplayId, HWC2::DisplayType::Virtual); display->setConnected(true); DisplayId displayId; if (mFreeVirtualDisplayIds.empty()) { displayId = getVirtualDisplayId(mNextVirtualDisplayId++); Loading @@ -214,7 +320,7 @@ std::optional<DisplayId> HWComposer::allocateVirtualDisplay(uint32_t width, uint } auto& displayData = mDisplayData[displayId]; displayData.hwcDisplay = display; displayData.hwcDisplay = std::move(display); displayData.isVirtual = true; --mRemainingHwcVirtualDisplays; Loading @@ -224,9 +330,8 @@ std::optional<DisplayId> HWComposer::allocateVirtualDisplay(uint32_t width, uint HWC2::Layer* HWComposer::createLayer(DisplayId displayId) { RETURN_IF_INVALID_DISPLAY(displayId, nullptr); auto display = mDisplayData[displayId].hwcDisplay; HWC2::Layer* layer; auto error = display->createLayer(&layer); auto error = mDisplayData[displayId].hwcDisplay->createLayer(&layer); RETURN_IF_HWC_ERROR(error, displayId, nullptr); return layer; } Loading @@ -234,8 +339,7 @@ HWC2::Layer* HWComposer::createLayer(DisplayId displayId) { void HWComposer::destroyLayer(DisplayId displayId, HWC2::Layer* layer) { RETURN_IF_INVALID_DISPLAY(displayId); auto display = mDisplayData[displayId].hwcDisplay; auto error = display->destroyLayer(layer); auto error = mDisplayData[displayId].hwcDisplay->destroyLayer(layer); RETURN_IF_HWC_ERROR(error, displayId); } Loading Loading @@ -484,8 +588,8 @@ status_t HWComposer::presentAndGetReleaseFences(DisplayId displayId) { if (displayData.validateWasSkipped) { // explicitly flush all pending commands auto error = mHwcDevice->flushCommands(); RETURN_IF_HWC_ERROR_FOR("flushCommands", error, displayId, UNKNOWN_ERROR); auto error = static_cast<HWC2::Error>(mComposer->executeCommands()); RETURN_IF_HWC_ERROR_FOR("executeCommands", error, displayId, UNKNOWN_ERROR); RETURN_IF_HWC_ERROR_FOR("present", displayData.presentError, displayId, UNKNOWN_ERROR); return NO_ERROR; } Loading Loading @@ -600,8 +704,6 @@ void HWComposer::disconnectDisplay(DisplayId displayId) { } const auto hwcDisplayId = displayData.hwcDisplay->getId(); mPhysicalDisplayIdMap.erase(hwcDisplayId); mDisplayData.erase(displayId); // TODO(b/74619554): Select internal/external display from remaining displays. if (hwcDisplayId == mInternalHwcDisplayId) { Loading @@ -609,8 +711,8 @@ void HWComposer::disconnectDisplay(DisplayId displayId) { } else if (hwcDisplayId == mExternalHwcDisplayId) { mExternalHwcDisplayId.reset(); } mHwcDevice->destroyDisplay(hwcDisplayId); mPhysicalDisplayIdMap.erase(hwcDisplayId); mDisplayData.erase(displayId); } status_t HWComposer::setOutputBuffer(DisplayId displayId, const sp<Fence>& acquireFence, Loading Loading @@ -761,10 +863,7 @@ status_t HWComposer::setContentType(DisplayId displayId, HWC2::ContentType conte } void HWComposer::dump(std::string& result) const { // TODO: In order to provide a dump equivalent to HWC1, we need to shadow // all the state going into the layers. This is probably better done in // Layer itself, but it's going to take a bit of work to get there. result.append(mHwcDevice->dump()); result.append(mComposer->dumpDebugInfo()); } std::optional<DisplayId> HWComposer::toPhysicalDisplayId(hwc2_display_t hwcDisplayId) const { Loading Loading @@ -830,5 +929,17 @@ std::optional<DisplayIdentificationInfo> HWComposer::onHotplugConnect(hwc2_displ : "External display"}; } void HWComposer::loadCapabilities() { static_assert(sizeof(HWC2::Capability) == sizeof(int32_t), "Capability size has changed"); auto capabilities = mComposer->getCapabilities(); for (auto capability : capabilities) { mCapabilities.emplace(static_cast<HWC2::Capability>(capability)); } } uint32_t HWComposer::getMaxVirtualDisplayCount() const { return mComposer->getMaxVirtualDisplayCount(); } } // namespace impl } // namespace android services/surfaceflinger/DisplayHardware/HWComposer.h +9 −7 Original line number Diff line number Diff line Loading @@ -207,6 +207,7 @@ namespace impl { class HWComposer final : public android::HWComposer { public: explicit HWComposer(std::unique_ptr<Hwc2::Composer> composer); explicit HWComposer(const std::string& composerServiceName); ~HWComposer() override; Loading Loading @@ -325,7 +326,7 @@ public: // for debugging ---------------------------------------------------------- void dump(std::string& out) const override; Hwc2::Composer* getComposer() const override { return mHwcDevice->getComposer(); } Hwc2::Composer* getComposer() const override { return mComposer.get(); } // TODO(b/74619554): Remove special cases for internal/external display. std::optional<hwc2_display_t> getInternalHwcDisplayId() const override { Loading @@ -343,11 +344,12 @@ private: friend TestableSurfaceFlinger; std::optional<DisplayIdentificationInfo> onHotplugConnect(hwc2_display_t hwcDisplayId); void loadCapabilities(); uint32_t getMaxVirtualDisplayCount() const; struct DisplayData { bool isVirtual = false; HWC2::Display* hwcDisplay = nullptr; std::unique_ptr<HWC2::Display> hwcDisplay; sp<Fence> lastPresentFence = Fence::NO_FENCE; // signals when the last set op retires std::unordered_map<HWC2::Layer*, sp<Fence>> releaseFences; buffer_handle_t outbufHandle = nullptr; Loading @@ -369,9 +371,9 @@ private: std::unordered_map<DisplayId, DisplayData> mDisplayData; // This must be destroyed before mDisplayData, because destructor may call back into HWComposer // and look up DisplayData. std::unique_ptr<HWC2::Device> mHwcDevice; std::unique_ptr<android::Hwc2::Composer> mComposer; std::unordered_set<HWC2::Capability> mCapabilities; bool mRegisteredCallback = false; std::unordered_map<hwc2_display_t, DisplayId> mPhysicalDisplayIdMap; std::optional<hwc2_display_t> mInternalHwcDisplayId; Loading @@ -380,7 +382,7 @@ private: std::unordered_set<DisplayId> mFreeVirtualDisplayIds; uint32_t mNextVirtualDisplayId = 0; uint32_t mRemainingHwcVirtualDisplays{mHwcDevice->getMaxVirtualDisplayCount()}; uint32_t mRemainingHwcVirtualDisplays{getMaxVirtualDisplayCount()}; }; } // namespace impl Loading services/surfaceflinger/SurfaceFlingerDefaultFactory.cpp +1 −2 Original line number Diff line number Diff line Loading @@ -52,8 +52,7 @@ std::unique_ptr<EventControlThread> DefaultFactory::createEventControlThread( } std::unique_ptr<HWComposer> DefaultFactory::createHWComposer(const std::string& serviceName) { return std::make_unique<android::impl::HWComposer>( std::make_unique<Hwc2::impl::Composer>(serviceName)); return std::make_unique<android::impl::HWComposer>(serviceName); } std::unique_ptr<MessageQueue> DefaultFactory::createMessageQueue() { Loading Loading
services/surfaceflinger/DisplayHardware/HWC2.cpp +0 −182 Original line number Diff line number Diff line Loading @@ -42,8 +42,6 @@ using android::HdrMetadata; using android::Rect; using android::Region; using android::sp; using android::hardware::Return; using android::hardware::Void; namespace HWC2 { Loading @@ -60,188 +58,8 @@ inline bool hasMetadataKey(const std::set<Hwc2::PerFrameMetadataKey>& keys, return keys.find(key) != keys.end(); } class ComposerCallbackBridge : public Hwc2::IComposerCallback { public: ComposerCallbackBridge(ComposerCallback* callback, int32_t sequenceId, bool vsyncSwitchingSupported) : mCallback(callback), mSequenceId(sequenceId), mVsyncSwitchingSupported(vsyncSwitchingSupported) {} Return<void> onHotplug(Hwc2::Display display, IComposerCallback::Connection conn) override { HWC2::Connection connection = static_cast<HWC2::Connection>(conn); mCallback->onHotplugReceived(mSequenceId, display, connection); return Void(); } Return<void> onRefresh(Hwc2::Display display) override { mCallback->onRefreshReceived(mSequenceId, display); return Void(); } Return<void> onVsync(Hwc2::Display display, int64_t timestamp) override { if (!mVsyncSwitchingSupported) { mCallback->onVsyncReceived(mSequenceId, display, timestamp, std::nullopt); } else { ALOGW("Unexpected onVsync callback on composer >= 2.4, ignoring."); } return Void(); } Return<void> onVsync_2_4(Hwc2::Display display, int64_t timestamp, Hwc2::VsyncPeriodNanos vsyncPeriodNanos) override { if (mVsyncSwitchingSupported) { // TODO(b/140201379): use vsyncPeriodNanos in the new DispSync mCallback->onVsyncReceived(mSequenceId, display, timestamp, std::make_optional(vsyncPeriodNanos)); } else { ALOGW("Unexpected onVsync_2_4 callback on composer <= 2.3, ignoring."); } return Void(); } Return<void> onVsyncPeriodTimingChanged( Hwc2::Display display, const Hwc2::VsyncPeriodChangeTimeline& updatedTimeline) override { hwc_vsync_period_change_timeline_t timeline; timeline.newVsyncAppliedTimeNanos = updatedTimeline.newVsyncAppliedTimeNanos; timeline.refreshRequired = updatedTimeline.refreshRequired; timeline.refreshTimeNanos = updatedTimeline.refreshTimeNanos; mCallback->onVsyncPeriodTimingChangedReceived(mSequenceId, display, timeline); return Void(); } private: ComposerCallback* mCallback; int32_t mSequenceId; const bool mVsyncSwitchingSupported; }; } // namespace anonymous // Device methods Device::Device(std::unique_ptr<android::Hwc2::Composer> composer) : mComposer(std::move(composer)) { loadCapabilities(); } void Device::registerCallback(ComposerCallback* callback, int32_t sequenceId) { if (mRegisteredCallback) { ALOGW("Callback already registered. Ignored extra registration " "attempt."); return; } mRegisteredCallback = true; sp<ComposerCallbackBridge> callbackBridge( new ComposerCallbackBridge(callback, sequenceId, mComposer->isVsyncPeriodSwitchSupported())); mComposer->registerCallback(callbackBridge); } // Required by HWC2 device std::string Device::dump() const { return mComposer->dumpDebugInfo(); } uint32_t Device::getMaxVirtualDisplayCount() const { return mComposer->getMaxVirtualDisplayCount(); } Error Device::getDisplayIdentificationData(hwc2_display_t hwcDisplayId, uint8_t* outPort, std::vector<uint8_t>* outData) const { auto intError = mComposer->getDisplayIdentificationData(hwcDisplayId, outPort, outData); return static_cast<Error>(intError); } Error Device::createVirtualDisplay(uint32_t width, uint32_t height, PixelFormat* format, Display** outDisplay) { ALOGI("Creating virtual display"); hwc2_display_t displayId = 0; auto intError = mComposer->createVirtualDisplay(width, height, format, &displayId); auto error = static_cast<Error>(intError); if (error != Error::None) { return error; } auto display = std::make_unique<impl::Display>(*mComposer.get(), mCapabilities, displayId, DisplayType::Virtual); display->setConnected(true); *outDisplay = display.get(); mDisplays.emplace(displayId, std::move(display)); ALOGI("Created virtual display"); return Error::None; } void Device::destroyDisplay(hwc2_display_t displayId) { ALOGI("Destroying display %" PRIu64, displayId); mDisplays.erase(displayId); } void Device::onHotplug(hwc2_display_t displayId, Connection connection) { if (connection == Connection::Connected) { // If we get a hotplug connected event for a display we already have, // destroy the display and recreate it. This will force us to requery // the display params and recreate all layers on that display. auto oldDisplay = getDisplayById(displayId); if (oldDisplay != nullptr && oldDisplay->isConnected()) { ALOGI("Hotplug connecting an already connected display." " Clearing old display state."); } mDisplays.erase(displayId); auto newDisplay = std::make_unique<impl::Display>(*mComposer.get(), mCapabilities, displayId, DisplayType::Physical); newDisplay->setConnected(true); mDisplays.emplace(displayId, std::move(newDisplay)); } else if (connection == Connection::Disconnected) { // The display will later be destroyed by a call to // destroyDisplay(). For now we just mark it disconnected. auto display = getDisplayById(displayId); if (display) { display->setConnected(false); } else { ALOGW("Attempted to disconnect unknown display %" PRIu64, displayId); } } } // Other Device methods Display* Device::getDisplayById(hwc2_display_t id) { auto iter = mDisplays.find(id); return iter == mDisplays.end() ? nullptr : iter->second.get(); } // Device initialization methods void Device::loadCapabilities() { static_assert(sizeof(Capability) == sizeof(int32_t), "Capability size has changed"); auto capabilities = mComposer->getCapabilities(); for (auto capability : capabilities) { mCapabilities.emplace(static_cast<Capability>(capability)); } } Error Device::flushCommands() { return static_cast<Error>(mComposer->executeCommands()); } // Display methods Display::~Display() = default; Loading
services/surfaceflinger/DisplayHardware/HWC2.h +0 −51 Original line number Diff line number Diff line Loading @@ -52,7 +52,6 @@ namespace android { namespace HWC2 { class Display; class Layer; using VsyncPeriodChangeConstraints = hwc_vsync_period_change_constraints_t; using VsyncPeriodChangeTimeline = hwc_vsync_period_change_timeline_t; Loading Loading @@ -81,56 +80,6 @@ class ComposerCallback { virtual ~ComposerCallback() = default; }; // C++ Wrapper around hwc2_device_t. Load all functions pointers // and handle callback registration. class Device { public: explicit Device(std::unique_ptr<android::Hwc2::Composer> composer); void registerCallback(ComposerCallback* callback, int32_t sequenceId); // Required by HWC2 std::string dump() const; const std::unordered_set<Capability>& getCapabilities() const { return mCapabilities; }; uint32_t getMaxVirtualDisplayCount() const; Error getDisplayIdentificationData(hwc2_display_t hwcDisplayId, uint8_t* outPort, std::vector<uint8_t>* outData) const; Error createVirtualDisplay(uint32_t width, uint32_t height, android::ui::PixelFormat* format, Display** outDisplay); void destroyDisplay(hwc2_display_t displayId); void onHotplug(hwc2_display_t displayId, Connection connection); // Other Device methods Display* getDisplayById(hwc2_display_t id); android::Hwc2::Composer* getComposer() { return mComposer.get(); } // We buffer most state changes and flush them implicitly with // Display::validate, Display::present, and Display::presentOrValidate. // This method provides an explicit way to flush state changes to HWC. Error flushCommands(); private: // Initialization methods void loadCapabilities(); // Member variables std::unique_ptr<android::Hwc2::Composer> mComposer; std::unordered_set<Capability> mCapabilities; std::unordered_map<hwc2_display_t, std::unique_ptr<Display>> mDisplays; bool mRegisteredCallback = false; }; // Convenience C++ class to access hwc2_device_t Display functions directly. class Display { public: Loading
services/surfaceflinger/DisplayHardware/HWComposer.cpp +141 −30 Original line number Diff line number Diff line Loading @@ -65,14 +65,88 @@ #define RETURN_IF_HWC_ERROR(error, displayId, ...) \ RETURN_IF_HWC_ERROR_FOR(__FUNCTION__, error, displayId, __VA_ARGS__) namespace { using android::hardware::Return; using android::hardware::Void; class ComposerCallbackBridge : public android::Hwc2::IComposerCallback { public: ComposerCallbackBridge(HWC2::ComposerCallback* callback, int32_t sequenceId, bool vsyncSwitchingSupported) : mCallback(callback), mSequenceId(sequenceId), mVsyncSwitchingSupported(vsyncSwitchingSupported) {} android::hardware::Return<void> onHotplug( android::Hwc2::Display display, android::Hwc2::IComposerCallback::Connection conn) override { HWC2::Connection connection = static_cast<HWC2::Connection>(conn); mCallback->onHotplugReceived(mSequenceId, display, connection); return android::hardware::Void(); } android::hardware::Return<void> onRefresh(android::Hwc2::Display display) override { mCallback->onRefreshReceived(mSequenceId, display); return android::hardware::Void(); } android::hardware::Return<void> onVsync(android::Hwc2::Display display, int64_t timestamp) override { if (!mVsyncSwitchingSupported) { mCallback->onVsyncReceived(mSequenceId, display, timestamp, std::nullopt); } else { ALOGW("Unexpected onVsync callback on composer >= 2.4, ignoring."); } return android::hardware::Void(); } android::hardware::Return<void> onVsync_2_4( android::Hwc2::Display display, int64_t timestamp, android::Hwc2::VsyncPeriodNanos vsyncPeriodNanos) override { if (mVsyncSwitchingSupported) { // TODO(b/140201379): use vsyncPeriodNanos in the new DispSync mCallback->onVsyncReceived(mSequenceId, display, timestamp, std::make_optional(vsyncPeriodNanos)); } else { ALOGW("Unexpected onVsync_2_4 callback on composer <= 2.3, ignoring."); } return android::hardware::Void(); } android::hardware::Return<void> onVsyncPeriodTimingChanged( android::Hwc2::Display display, const android::Hwc2::VsyncPeriodChangeTimeline& updatedTimeline) override { hwc_vsync_period_change_timeline_t timeline; timeline.newVsyncAppliedTimeNanos = updatedTimeline.newVsyncAppliedTimeNanos; timeline.refreshRequired = updatedTimeline.refreshRequired; timeline.refreshTimeNanos = updatedTimeline.refreshTimeNanos; mCallback->onVsyncPeriodTimingChangedReceived(mSequenceId, display, timeline); return android::hardware::Void(); } private: HWC2::ComposerCallback* mCallback; const int32_t mSequenceId; const bool mVsyncSwitchingSupported; }; } // namespace namespace android { HWComposer::~HWComposer() = default; namespace impl { HWComposer::HWComposer(std::unique_ptr<Hwc2::Composer> composer) : mHwcDevice(std::make_unique<HWC2::Device>(std::move(composer))) {} HWComposer::HWComposer(std::unique_ptr<Hwc2::Composer> composer) : mComposer(std::move(composer)) { loadCapabilities(); } HWComposer::HWComposer(const std::string& composerServiceName) : mComposer(std::make_unique<Hwc2::impl::Composer>(composerServiceName)) { loadCapabilities(); } HWComposer::~HWComposer() { mDisplayData.clear(); Loading @@ -80,12 +154,21 @@ HWComposer::~HWComposer() { void HWComposer::registerCallback(HWC2::ComposerCallback* callback, int32_t sequenceId) { mHwcDevice->registerCallback(callback, sequenceId); if (mRegisteredCallback) { ALOGW("Callback already registered. Ignored extra registration attempt."); return; } mRegisteredCallback = true; sp<ComposerCallbackBridge> callbackBridge( new ComposerCallbackBridge(callback, sequenceId, mComposer->isVsyncPeriodSwitchSupported())); mComposer->registerCallback(callbackBridge); } bool HWComposer::getDisplayIdentificationData(hwc2_display_t hwcDisplayId, uint8_t* outPort, DisplayIdentificationData* outData) const { const auto error = mHwcDevice->getDisplayIdentificationData(hwcDisplayId, outPort, outData); const auto error = static_cast<HWC2::Error>( mComposer->getDisplayIdentificationData(hwcDisplayId, outPort, outData)); if (error != HWC2::Error::None) { if (error != HWC2::Error::Unsupported) { LOG_HWC_DISPLAY_ERROR(hwcDisplayId, to_string(error).c_str()); Loading @@ -95,9 +178,8 @@ bool HWComposer::getDisplayIdentificationData(hwc2_display_t hwcDisplayId, uint8 return true; } bool HWComposer::hasCapability(HWC2::Capability capability) const { return mHwcDevice->getCapabilities().count(capability) > 0; bool HWComposer::hasCapability(HWC2::Capability capability) const { return mCapabilities.count(capability) > 0; } bool HWComposer::hasDisplayCapability(const std::optional<DisplayId>& displayId, Loading Loading @@ -133,13 +215,33 @@ std::optional<DisplayIdentificationInfo> HWComposer::onHotplug(hwc2_display_t hw hwcDisplayId == mInternalHwcDisplayId ? "internal" : "external", to_string(info->id).c_str(), hwcDisplayId); mHwcDevice->onHotplug(hwcDisplayId, connection); // Disconnect is handled through HWComposer::disconnectDisplay via // SurfaceFlinger's onHotplugReceived callback handling if (connection == HWC2::Connection::Connected) { mDisplayData[info->id].hwcDisplay = mHwcDevice->getDisplayById(hwcDisplayId); auto& displayData = mDisplayData[info->id]; // If we get a hotplug connected event for a display we already have, // destroy the display and recreate it. This will force us to requery // the display params and recreate all layers on that display. if (displayData.hwcDisplay != nullptr && displayData.hwcDisplay->isConnected()) { ALOGI("Hotplug connecting an already connected display." " Clearing old display state."); } displayData.hwcDisplay.reset(); auto newDisplay = std::make_unique<HWC2::impl::Display>(*mComposer.get(), mCapabilities, hwcDisplayId, HWC2::DisplayType::Physical); newDisplay->setConnected(true); displayData.hwcDisplay = std::move(newDisplay); mPhysicalDisplayIdMap[hwcDisplayId] = info->id; } else if (connection == HWC2::Connection::Disconnected) { // The display will later be destroyed by a call to // destroyDisplay(). For now we just mark it disconnected. auto& displayData = mDisplayData[info->id]; if (displayData.hwcDisplay) { displayData.hwcDisplay->setConnected(false); } else { ALOGW("Attempted to disconnect unknown display %" PRIu64, hwcDisplayId); } // The cleanup of Disconnect is handled through HWComposer::disconnectDisplay // via SurfaceFlinger's onHotplugReceived callback handling } return info; Loading Loading @@ -197,14 +299,18 @@ std::optional<DisplayId> HWComposer::allocateVirtualDisplay(uint32_t width, uint height, SurfaceFlinger::maxVirtualDisplaySize); return {}; } HWC2::Display* display; auto error = mHwcDevice->createVirtualDisplay(width, height, format, &display); hwc2_display_t hwcDisplayId = 0; const auto error = static_cast<HWC2::Error>( mComposer->createVirtualDisplay(width, height, format, &hwcDisplayId)); if (error != HWC2::Error::None) { ALOGE("%s: Failed to create HWC virtual display", __FUNCTION__); return {}; } auto display = std::make_unique<HWC2::impl::Display>(*mComposer.get(), mCapabilities, hwcDisplayId, HWC2::DisplayType::Virtual); display->setConnected(true); DisplayId displayId; if (mFreeVirtualDisplayIds.empty()) { displayId = getVirtualDisplayId(mNextVirtualDisplayId++); Loading @@ -214,7 +320,7 @@ std::optional<DisplayId> HWComposer::allocateVirtualDisplay(uint32_t width, uint } auto& displayData = mDisplayData[displayId]; displayData.hwcDisplay = display; displayData.hwcDisplay = std::move(display); displayData.isVirtual = true; --mRemainingHwcVirtualDisplays; Loading @@ -224,9 +330,8 @@ std::optional<DisplayId> HWComposer::allocateVirtualDisplay(uint32_t width, uint HWC2::Layer* HWComposer::createLayer(DisplayId displayId) { RETURN_IF_INVALID_DISPLAY(displayId, nullptr); auto display = mDisplayData[displayId].hwcDisplay; HWC2::Layer* layer; auto error = display->createLayer(&layer); auto error = mDisplayData[displayId].hwcDisplay->createLayer(&layer); RETURN_IF_HWC_ERROR(error, displayId, nullptr); return layer; } Loading @@ -234,8 +339,7 @@ HWC2::Layer* HWComposer::createLayer(DisplayId displayId) { void HWComposer::destroyLayer(DisplayId displayId, HWC2::Layer* layer) { RETURN_IF_INVALID_DISPLAY(displayId); auto display = mDisplayData[displayId].hwcDisplay; auto error = display->destroyLayer(layer); auto error = mDisplayData[displayId].hwcDisplay->destroyLayer(layer); RETURN_IF_HWC_ERROR(error, displayId); } Loading Loading @@ -484,8 +588,8 @@ status_t HWComposer::presentAndGetReleaseFences(DisplayId displayId) { if (displayData.validateWasSkipped) { // explicitly flush all pending commands auto error = mHwcDevice->flushCommands(); RETURN_IF_HWC_ERROR_FOR("flushCommands", error, displayId, UNKNOWN_ERROR); auto error = static_cast<HWC2::Error>(mComposer->executeCommands()); RETURN_IF_HWC_ERROR_FOR("executeCommands", error, displayId, UNKNOWN_ERROR); RETURN_IF_HWC_ERROR_FOR("present", displayData.presentError, displayId, UNKNOWN_ERROR); return NO_ERROR; } Loading Loading @@ -600,8 +704,6 @@ void HWComposer::disconnectDisplay(DisplayId displayId) { } const auto hwcDisplayId = displayData.hwcDisplay->getId(); mPhysicalDisplayIdMap.erase(hwcDisplayId); mDisplayData.erase(displayId); // TODO(b/74619554): Select internal/external display from remaining displays. if (hwcDisplayId == mInternalHwcDisplayId) { Loading @@ -609,8 +711,8 @@ void HWComposer::disconnectDisplay(DisplayId displayId) { } else if (hwcDisplayId == mExternalHwcDisplayId) { mExternalHwcDisplayId.reset(); } mHwcDevice->destroyDisplay(hwcDisplayId); mPhysicalDisplayIdMap.erase(hwcDisplayId); mDisplayData.erase(displayId); } status_t HWComposer::setOutputBuffer(DisplayId displayId, const sp<Fence>& acquireFence, Loading Loading @@ -761,10 +863,7 @@ status_t HWComposer::setContentType(DisplayId displayId, HWC2::ContentType conte } void HWComposer::dump(std::string& result) const { // TODO: In order to provide a dump equivalent to HWC1, we need to shadow // all the state going into the layers. This is probably better done in // Layer itself, but it's going to take a bit of work to get there. result.append(mHwcDevice->dump()); result.append(mComposer->dumpDebugInfo()); } std::optional<DisplayId> HWComposer::toPhysicalDisplayId(hwc2_display_t hwcDisplayId) const { Loading Loading @@ -830,5 +929,17 @@ std::optional<DisplayIdentificationInfo> HWComposer::onHotplugConnect(hwc2_displ : "External display"}; } void HWComposer::loadCapabilities() { static_assert(sizeof(HWC2::Capability) == sizeof(int32_t), "Capability size has changed"); auto capabilities = mComposer->getCapabilities(); for (auto capability : capabilities) { mCapabilities.emplace(static_cast<HWC2::Capability>(capability)); } } uint32_t HWComposer::getMaxVirtualDisplayCount() const { return mComposer->getMaxVirtualDisplayCount(); } } // namespace impl } // namespace android
services/surfaceflinger/DisplayHardware/HWComposer.h +9 −7 Original line number Diff line number Diff line Loading @@ -207,6 +207,7 @@ namespace impl { class HWComposer final : public android::HWComposer { public: explicit HWComposer(std::unique_ptr<Hwc2::Composer> composer); explicit HWComposer(const std::string& composerServiceName); ~HWComposer() override; Loading Loading @@ -325,7 +326,7 @@ public: // for debugging ---------------------------------------------------------- void dump(std::string& out) const override; Hwc2::Composer* getComposer() const override { return mHwcDevice->getComposer(); } Hwc2::Composer* getComposer() const override { return mComposer.get(); } // TODO(b/74619554): Remove special cases for internal/external display. std::optional<hwc2_display_t> getInternalHwcDisplayId() const override { Loading @@ -343,11 +344,12 @@ private: friend TestableSurfaceFlinger; std::optional<DisplayIdentificationInfo> onHotplugConnect(hwc2_display_t hwcDisplayId); void loadCapabilities(); uint32_t getMaxVirtualDisplayCount() const; struct DisplayData { bool isVirtual = false; HWC2::Display* hwcDisplay = nullptr; std::unique_ptr<HWC2::Display> hwcDisplay; sp<Fence> lastPresentFence = Fence::NO_FENCE; // signals when the last set op retires std::unordered_map<HWC2::Layer*, sp<Fence>> releaseFences; buffer_handle_t outbufHandle = nullptr; Loading @@ -369,9 +371,9 @@ private: std::unordered_map<DisplayId, DisplayData> mDisplayData; // This must be destroyed before mDisplayData, because destructor may call back into HWComposer // and look up DisplayData. std::unique_ptr<HWC2::Device> mHwcDevice; std::unique_ptr<android::Hwc2::Composer> mComposer; std::unordered_set<HWC2::Capability> mCapabilities; bool mRegisteredCallback = false; std::unordered_map<hwc2_display_t, DisplayId> mPhysicalDisplayIdMap; std::optional<hwc2_display_t> mInternalHwcDisplayId; Loading @@ -380,7 +382,7 @@ private: std::unordered_set<DisplayId> mFreeVirtualDisplayIds; uint32_t mNextVirtualDisplayId = 0; uint32_t mRemainingHwcVirtualDisplays{mHwcDevice->getMaxVirtualDisplayCount()}; uint32_t mRemainingHwcVirtualDisplays{getMaxVirtualDisplayCount()}; }; } // namespace impl Loading
services/surfaceflinger/SurfaceFlingerDefaultFactory.cpp +1 −2 Original line number Diff line number Diff line Loading @@ -52,8 +52,7 @@ std::unique_ptr<EventControlThread> DefaultFactory::createEventControlThread( } std::unique_ptr<HWComposer> DefaultFactory::createHWComposer(const std::string& serviceName) { return std::make_unique<android::impl::HWComposer>( std::make_unique<Hwc2::impl::Composer>(serviceName)); return std::make_unique<android::impl::HWComposer>(serviceName); } std::unique_ptr<MessageQueue> DefaultFactory::createMessageQueue() { Loading