mirror of
https://gitlab.freedesktop.org/mesa/vulkan-wsi-layer.git
synced 2025-12-20 04:30:11 +01:00
Merge 'Add a workaround when wp_feedback events are not delivered' into 'main'
See merge request mesa/vulkan-wsi-layer!213
This commit is contained in:
commit
faf83d387b
9 changed files with 171 additions and 41 deletions
|
|
@ -25,6 +25,7 @@
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
|
@ -85,6 +86,25 @@ public:
|
||||||
return get((m_begin + m_size + N - 1) % N);
|
return get((m_begin + m_size + N - 1) % N);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Find element in the ring buffer
|
||||||
|
*
|
||||||
|
* @param predicate Predicate which returns a true value when element is matching.
|
||||||
|
* @return Pointer to the element, nullptr otherwise.
|
||||||
|
*/
|
||||||
|
T *find(std::function<bool(const T &el)> predicate)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < size(); i++)
|
||||||
|
{
|
||||||
|
if (predicate(*m_data[(m_begin + i) % N]))
|
||||||
|
{
|
||||||
|
return get((m_begin + i) % N);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Pop the front of the ring buffer.
|
* @brief Pop the front of the ring buffer.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ public:
|
||||||
/**
|
/**
|
||||||
* @brief Marks the given present ID delivered (i.e. its image has been displayed).
|
* @brief Marks the given present ID delivered (i.e. its image has been displayed).
|
||||||
*/
|
*/
|
||||||
void mark_delivered(uint64_t present_id);
|
virtual void mark_delivered(uint64_t present_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sets the error state for all pending and future image requests.
|
* @brief Sets the error state for all pending and future image requests.
|
||||||
|
|
|
||||||
|
|
@ -37,8 +37,22 @@ namespace wsi
|
||||||
namespace wayland
|
namespace wayland
|
||||||
{
|
{
|
||||||
|
|
||||||
presentation_feedback *wsi_ext_present_id_wayland::insert_into_pending_present_feedback_list(
|
void wsi_ext_present_id_wayland::mark_delivered(uint64_t present_id)
|
||||||
uint64_t present_id, struct wp_presentation_feedback *feedback_obj)
|
{
|
||||||
|
wsi_ext_present_id::mark_delivered(present_id);
|
||||||
|
remove_from_pending_present_feedback_list(present_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wsi_ext_present_id_wayland::mark_buffer_release(uint32_t image_index)
|
||||||
|
{
|
||||||
|
const auto present_id = get_present_id_from_image_index(image_index);
|
||||||
|
if (present_id > 0)
|
||||||
|
{
|
||||||
|
mark_delivered(present_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t wsi_ext_present_id_wayland::get_present_id_from_image_index(uint32_t image_index)
|
||||||
{
|
{
|
||||||
util::unique_lock<util::mutex> lock(m_pending_presents_lock);
|
util::unique_lock<util::mutex> lock(m_pending_presents_lock);
|
||||||
if (!lock)
|
if (!lock)
|
||||||
|
|
@ -46,7 +60,28 @@ presentation_feedback *wsi_ext_present_id_wayland::insert_into_pending_present_f
|
||||||
WSI_LOG_ERROR("Failed to acquire pending presents lock in insert_into_pending_present_feedback_list.\n");
|
WSI_LOG_ERROR("Failed to acquire pending presents lock in insert_into_pending_present_feedback_list.\n");
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
bool ret = m_pending_presents.push_back(presentation_feedback(feedback_obj, this, present_id));
|
|
||||||
|
auto feedback = m_pending_presents.find(
|
||||||
|
[image_index](const presentation_feedback &feedback) { return feedback.get_image_index() == image_index; });
|
||||||
|
|
||||||
|
return feedback != nullptr ? feedback->get_present_id() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
presentation_feedback *wsi_ext_present_id_wayland::insert_into_pending_present_feedback_list(
|
||||||
|
uint64_t present_id, uint32_t image_index, struct wp_presentation_feedback *feedback_obj)
|
||||||
|
{
|
||||||
|
util::unique_lock<util::mutex> lock(m_pending_presents_lock);
|
||||||
|
if (!lock)
|
||||||
|
{
|
||||||
|
WSI_LOG_ERROR("Failed to acquire pending presents lock in insert_into_pending_present_feedback_list.\n");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We should not be replacing pending entries. This most likely has happened due to events not being triggered
|
||||||
|
* that would discard or mark the pending present request as completed which could be an inidcation of a bug somewhere. */
|
||||||
|
assert(m_pending_presents.size() != m_pending_presents.capacity());
|
||||||
|
|
||||||
|
bool ret = m_pending_presents.push_back(presentation_feedback(feedback_obj, this, present_id, image_index));
|
||||||
if (!ret)
|
if (!ret)
|
||||||
{
|
{
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
|
||||||
|
|
@ -53,15 +53,37 @@ public:
|
||||||
/**
|
/**
|
||||||
* @brief Insert into pending present id list.
|
* @brief Insert into pending present id list.
|
||||||
*/
|
*/
|
||||||
presentation_feedback *insert_into_pending_present_feedback_list(uint64_t present_id,
|
presentation_feedback *insert_into_pending_present_feedback_list(uint64_t present_id, uint32_t image_index,
|
||||||
struct wp_presentation_feedback *feedback_obj);
|
struct wp_presentation_feedback *feedback_obj);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Marks the given present ID delivered (i.e. its image has been displayed).
|
||||||
|
*
|
||||||
|
* @param present_id Present ID to mark as delivered.
|
||||||
|
*/
|
||||||
|
virtual void mark_delivered(uint64_t present_id) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Marks the buffer as released for the given image index.
|
||||||
|
*
|
||||||
|
* @param image_index The index of the image in the swapchain.
|
||||||
|
*/
|
||||||
|
void mark_buffer_release(uint32_t image_index);
|
||||||
|
|
||||||
|
private:
|
||||||
/**
|
/**
|
||||||
* @brief Remove a present id from the pending present id list.
|
* @brief Remove a present id from the pending present id list.
|
||||||
*/
|
*/
|
||||||
void remove_from_pending_present_feedback_list(uint64_t present_id);
|
void remove_from_pending_present_feedback_list(uint64_t present_id);
|
||||||
|
|
||||||
private:
|
/**
|
||||||
|
* @brief Get the present id from image index object
|
||||||
|
*
|
||||||
|
* @param image_index Image index to check for.
|
||||||
|
* @return Present ID associated with the image index or 0 otherwise.
|
||||||
|
*/
|
||||||
|
uint64_t get_present_id_from_image_index(uint32_t image_index);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Mutex for synchronising accesses to the pending present id list.
|
* @brief Mutex for synchronising accesses to the pending present id list.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -97,6 +97,21 @@ VkResult wsi_ext_present_timing_wayland::get_swapchain_timing_properties(
|
||||||
return VK_SUCCESS;
|
return VK_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wsi_ext_present_timing_wayland::mark_delivered(uint32_t image_index, uint64_t time)
|
||||||
|
{
|
||||||
|
pixelout_callback(image_index, time);
|
||||||
|
remove_from_pending_present_feedback_list(image_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wsi_ext_present_timing_wayland::mark_buffer_release(uint32_t image_index)
|
||||||
|
{
|
||||||
|
auto was_removed = remove_from_pending_present_feedback_list(image_index);
|
||||||
|
if (was_removed)
|
||||||
|
{
|
||||||
|
pixelout_callback(image_index, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
presentation_feedback *wsi_ext_present_timing_wayland::insert_into_pending_present_feedback_list(
|
presentation_feedback *wsi_ext_present_timing_wayland::insert_into_pending_present_feedback_list(
|
||||||
uint32_t image_index, struct wp_presentation_feedback *feedback_obj)
|
uint32_t image_index, struct wp_presentation_feedback *feedback_obj)
|
||||||
{
|
{
|
||||||
|
|
@ -107,11 +122,16 @@ presentation_feedback *wsi_ext_present_timing_wayland::insert_into_pending_prese
|
||||||
WSI_LOG_ERROR("Failed to acquire pending presents lock in insert_into_pending_present_feedback_list.\n");
|
WSI_LOG_ERROR("Failed to acquire pending presents lock in insert_into_pending_present_feedback_list.\n");
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* We should not be replacing pending entries. This most likely has happened due to events not being triggered
|
||||||
|
* that would discard or mark the pending present request as completed which could be an inidcation of a bug somewhere. */
|
||||||
|
assert(!m_pending_presents[image_index].has_value());
|
||||||
|
|
||||||
m_pending_presents[image_index] = presentation_feedback(feedback_obj, this, image_index);
|
m_pending_presents[image_index] = presentation_feedback(feedback_obj, this, image_index);
|
||||||
return &m_pending_presents[image_index].value();
|
return &m_pending_presents[image_index].value();
|
||||||
}
|
}
|
||||||
|
|
||||||
void wsi_ext_present_timing_wayland::remove_from_pending_present_feedback_list(uint32_t image_index)
|
bool wsi_ext_present_timing_wayland::remove_from_pending_present_feedback_list(uint32_t image_index)
|
||||||
{
|
{
|
||||||
util::unique_lock<util::mutex> lock(m_pending_presents_lock);
|
util::unique_lock<util::mutex> lock(m_pending_presents_lock);
|
||||||
if (!lock)
|
if (!lock)
|
||||||
|
|
@ -119,7 +139,10 @@ void wsi_ext_present_timing_wayland::remove_from_pending_present_feedback_list(u
|
||||||
WSI_LOG_ERROR("Failed to acquire pending presents lock in remove_from_pending_present_feedback_list.\n");
|
WSI_LOG_ERROR("Failed to acquire pending presents lock in remove_from_pending_present_feedback_list.\n");
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const bool has_entry = m_pending_presents[image_index].has_value();
|
||||||
m_pending_presents[image_index].reset();
|
m_pending_presents[image_index].reset();
|
||||||
|
return has_entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wsi_ext_present_timing_wayland::pixelout_callback(uint32_t image_index, uint64_t time)
|
void wsi_ext_present_timing_wayland::pixelout_callback(uint32_t image_index, uint64_t time)
|
||||||
|
|
|
||||||
|
|
@ -31,12 +31,15 @@
|
||||||
|
|
||||||
#if VULKAN_WSI_LAYER_EXPERIMENTAL
|
#if VULKAN_WSI_LAYER_EXPERIMENTAL
|
||||||
|
|
||||||
#include <wsi/extensions/present_timing.hpp>
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
#include <array>
|
||||||
|
|
||||||
|
#include <wsi/extensions/present_timing.hpp>
|
||||||
|
#include <util/custom_mutex.hpp>
|
||||||
|
|
||||||
#include "surface_properties.hpp"
|
#include "surface_properties.hpp"
|
||||||
#include "wp_presentation_feedback.hpp"
|
#include "wp_presentation_feedback.hpp"
|
||||||
#include "wl_helpers.hpp"
|
#include "wl_helpers.hpp"
|
||||||
#include <util/custom_mutex.hpp>
|
|
||||||
|
|
||||||
namespace wsi
|
namespace wsi
|
||||||
{
|
{
|
||||||
|
|
@ -58,6 +61,24 @@ public:
|
||||||
VkResult get_swapchain_timing_properties(uint64_t &timing_properties_counter,
|
VkResult get_swapchain_timing_properties(uint64_t &timing_properties_counter,
|
||||||
VkSwapchainTimingPropertiesEXT &timing_properties) override;
|
VkSwapchainTimingPropertiesEXT &timing_properties) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Marks the given present ID delivered (i.e. its image has been displayed).
|
||||||
|
*
|
||||||
|
* @param image_index The index of the image in the swapchain.
|
||||||
|
* @param time The time to set for the first pixel out stage.
|
||||||
|
*
|
||||||
|
* Note: Time value of 0 specifies that request was discarded.
|
||||||
|
* Note: Time value is in nanoseconds.
|
||||||
|
*/
|
||||||
|
void mark_delivered(uint32_t image_index, uint64_t time);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Marks the buffer as released for the given image index.
|
||||||
|
*
|
||||||
|
* @param image_index The index of the image in the swapchain.
|
||||||
|
*/
|
||||||
|
void mark_buffer_release(uint32_t image_index);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Insert into pending present id list.
|
* @brief Insert into pending present id list.
|
||||||
*
|
*
|
||||||
|
|
@ -69,24 +90,6 @@ public:
|
||||||
*/
|
*/
|
||||||
presentation_feedback *insert_into_pending_present_feedback_list(uint32_t image_index,
|
presentation_feedback *insert_into_pending_present_feedback_list(uint32_t image_index,
|
||||||
struct wp_presentation_feedback *feedback_obj);
|
struct wp_presentation_feedback *feedback_obj);
|
||||||
/**
|
|
||||||
* @brief Remove a present id from the pending present id list.
|
|
||||||
*
|
|
||||||
* @param image_index The index of the image to be inserted in the list.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void remove_from_pending_present_feedback_list(uint32_t image_index);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Updates the first pixel out timing in the internal array.
|
|
||||||
*
|
|
||||||
* @param image_index The index of the image in the swapchain.
|
|
||||||
*
|
|
||||||
* @param time The time to set for the first pixel out stage.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void pixelout_callback(uint32_t image_index, uint64_t time);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @brief Copies the pixel out timestamp from the internal array to the present timing queue.
|
* @brief Copies the pixel out timestamp from the internal array to the present timing queue.
|
||||||
*
|
*
|
||||||
|
|
@ -122,6 +125,25 @@ private:
|
||||||
wsi_ext_present_timing_wayland(const util::allocator &allocator, VkDevice device, uint32_t num_images,
|
wsi_ext_present_timing_wayland(const util::allocator &allocator, VkDevice device, uint32_t num_images,
|
||||||
util::vector<std::optional<uint64_t>> &×tamp_first_pixel_out_storage);
|
util::vector<std::optional<uint64_t>> &×tamp_first_pixel_out_storage);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Updates the first pixel out timing in the internal array.
|
||||||
|
*
|
||||||
|
* @param image_index The index of the image in the swapchain.
|
||||||
|
*
|
||||||
|
* @param time The time to set for the first pixel out stage.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void pixelout_callback(uint32_t image_index, uint64_t time);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Remove a present id from the pending present id list.
|
||||||
|
*
|
||||||
|
* @param image_index The index of the image to be inserted in the list.
|
||||||
|
*
|
||||||
|
* @return true if entry was removed, false if it was not found.
|
||||||
|
*/
|
||||||
|
bool remove_from_pending_present_feedback_list(uint32_t image_index);
|
||||||
|
|
||||||
wl_display *m_display{};
|
wl_display *m_display{};
|
||||||
struct wl_event_queue *m_queue{};
|
struct wl_event_queue *m_queue{};
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -235,6 +235,22 @@ void swapchain::release_buffer(struct wl_buffer *wayl_buffer)
|
||||||
auto data = reinterpret_cast<wayland_image_data *>(m_swapchain_images[i].data);
|
auto data = reinterpret_cast<wayland_image_data *>(m_swapchain_images[i].data);
|
||||||
if (data && data->buffer == wayl_buffer)
|
if (data && data->buffer == wayl_buffer)
|
||||||
{
|
{
|
||||||
|
#if VULKAN_WSI_LAYER_EXPERIMENTAL
|
||||||
|
/* Some compositors might not deliver wp_presentation_feedback events if the images are pushed to compositor quick enough
|
||||||
|
* in presentation modes that allow it (mailbox). If that happens, double check if these images were submitted for feedback
|
||||||
|
* and handle it as a 'image discarded' event. */
|
||||||
|
auto *present_timing_ext = get_swapchain_extension<wsi_ext_present_timing_wayland>();
|
||||||
|
if (present_timing_ext != nullptr)
|
||||||
|
{
|
||||||
|
present_timing_ext->mark_buffer_release(i);
|
||||||
|
}
|
||||||
|
auto *present_id_ext = get_swapchain_extension<wsi_ext_present_id_wayland>();
|
||||||
|
if (present_id_ext != nullptr)
|
||||||
|
{
|
||||||
|
present_id_ext->mark_buffer_release(i);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
unpresent_image(i);
|
unpresent_image(i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -603,8 +619,8 @@ void swapchain::present_image(const pending_present_request &pending_present)
|
||||||
wp_presentation *pres = m_wsi_surface->get_presentation_time_interface();
|
wp_presentation *pres = m_wsi_surface->get_presentation_time_interface();
|
||||||
struct wp_presentation_feedback *feedback = wp_presentation_feedback(pres, m_wsi_surface->get_wl_surface());
|
struct wp_presentation_feedback *feedback = wp_presentation_feedback(pres, m_wsi_surface->get_wl_surface());
|
||||||
wl_proxy_set_queue(reinterpret_cast<wl_proxy *>(feedback), m_buffer_queue);
|
wl_proxy_set_queue(reinterpret_cast<wl_proxy *>(feedback), m_buffer_queue);
|
||||||
presentation_feedback *feedback_obj =
|
presentation_feedback *feedback_obj = present_id_ext->insert_into_pending_present_feedback_list(
|
||||||
present_id_ext->insert_into_pending_present_feedback_list(pending_present.present_id, feedback);
|
pending_present.present_id, pending_present.image_index, feedback);
|
||||||
if (feedback_obj == nullptr)
|
if (feedback_obj == nullptr)
|
||||||
{
|
{
|
||||||
WSI_LOG_ERROR("Error adding to pending present feedback list");
|
WSI_LOG_ERROR("Error adding to pending present feedback list");
|
||||||
|
|
|
||||||
|
|
@ -52,13 +52,11 @@ wp_presentation_feedback_presented(void *data, struct wp_presentation_feedback *
|
||||||
timestamp_seconds = static_cast<uint64_t>(std::floor(timestamp_limit));
|
timestamp_seconds = static_cast<uint64_t>(std::floor(timestamp_limit));
|
||||||
}
|
}
|
||||||
uint64_t timestamp_ns = static_cast<uint64_t>(timestamp_seconds * 1e9) + tv_nsec;
|
uint64_t timestamp_ns = static_cast<uint64_t>(timestamp_seconds * 1e9) + tv_nsec;
|
||||||
feedback_obj->ext_present_timing()->pixelout_callback(feedback_obj->get_image_index(), timestamp_ns);
|
feedback_obj->ext_present_timing()->mark_delivered(feedback_obj->get_image_index(), timestamp_ns);
|
||||||
feedback_obj->ext_present_timing()->remove_from_pending_present_feedback_list(feedback_obj->get_image_index());
|
|
||||||
}
|
}
|
||||||
else if (feedback_obj->ext_present_id() != nullptr)
|
else if (feedback_obj->ext_present_id() != nullptr)
|
||||||
{
|
{
|
||||||
feedback_obj->ext_present_id()->mark_delivered(feedback_obj->get_present_id());
|
feedback_obj->ext_present_id()->mark_delivered(feedback_obj->get_present_id());
|
||||||
feedback_obj->ext_present_id()->remove_from_pending_present_feedback_list(feedback_obj->get_present_id());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -72,12 +70,10 @@ wp_presentation_feedback_discarded(void *data, struct wp_presentation_feedback *
|
||||||
if (feedback_obj->ext_present_id() != nullptr)
|
if (feedback_obj->ext_present_id() != nullptr)
|
||||||
{
|
{
|
||||||
feedback_obj->ext_present_id()->mark_delivered(feedback_obj->get_present_id());
|
feedback_obj->ext_present_id()->mark_delivered(feedback_obj->get_present_id());
|
||||||
feedback_obj->ext_present_id()->remove_from_pending_present_feedback_list(feedback_obj->get_present_id());
|
|
||||||
}
|
}
|
||||||
if (feedback_obj->ext_present_timing() != nullptr)
|
if (feedback_obj->ext_present_timing() != nullptr)
|
||||||
{
|
{
|
||||||
feedback_obj->ext_present_timing()->pixelout_callback(feedback_obj->get_image_index(), 0);
|
feedback_obj->ext_present_timing()->mark_delivered(feedback_obj->get_image_index(), 0);
|
||||||
feedback_obj->ext_present_timing()->remove_from_pending_present_feedback_list(feedback_obj->get_image_index());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -66,12 +66,12 @@ public:
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
presentation_feedback(struct wp_presentation_feedback *feedback, wsi_ext_present_id_wayland *ext_present_id,
|
presentation_feedback(struct wp_presentation_feedback *feedback, wsi_ext_present_id_wayland *ext_present_id,
|
||||||
uint64_t present_id)
|
uint64_t present_id, uint32_t image_index)
|
||||||
: m_feedback(feedback)
|
: m_feedback(feedback)
|
||||||
, m_ext_present_id(ext_present_id)
|
, m_ext_present_id(ext_present_id)
|
||||||
, m_present_id(present_id)
|
, m_present_id(present_id)
|
||||||
, m_ext_present_timing(nullptr)
|
, m_ext_present_timing(nullptr)
|
||||||
, m_image_index(0)
|
, m_image_index(image_index)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -94,10 +94,6 @@ public:
|
||||||
{
|
{
|
||||||
if (this != &feedback_obj)
|
if (this != &feedback_obj)
|
||||||
{
|
{
|
||||||
if (m_feedback != nullptr)
|
|
||||||
{
|
|
||||||
wp_presentation_feedback_destroy(m_feedback.get());
|
|
||||||
}
|
|
||||||
m_present_id = feedback_obj.m_present_id;
|
m_present_id = feedback_obj.m_present_id;
|
||||||
m_feedback = std::move(feedback_obj.m_feedback);
|
m_feedback = std::move(feedback_obj.m_feedback);
|
||||||
m_ext_present_id = feedback_obj.m_ext_present_id;
|
m_ext_present_id = feedback_obj.m_ext_present_id;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue