未验证 提交 a37560a0 编写于 作者: C Chinmay Garde 提交者: GitHub

Use the standard [[nodiscard]] attribute instead of an FML macro. (#17100)

上级 8c8b3e1d
......@@ -21,8 +21,7 @@ class AssetResolver {
virtual bool IsValid() const = 0;
FML_WARN_UNUSED_RESULT
virtual std::unique_ptr<fml::Mapping> GetAsMapping(
[[nodiscard]] virtual std::unique_ptr<fml::Mapping> GetAsMapping(
const std::string& asset_name) const = 0;
private:
......
......@@ -84,7 +84,7 @@ class Layer {
// destruction.
class AutoPrerollSaveLayerState {
public:
FML_WARN_UNUSED_RESULT static AutoPrerollSaveLayerState Create(
[[nodiscard]] static AutoPrerollSaveLayerState Create(
PrerollContext* preroll_context,
bool save_layer_is_active = true,
bool layer_itself_performs_readback = false);
......@@ -133,12 +133,11 @@ class Layer {
// draws a checkerboard over the layer if that is enabled in the PaintContext.
class AutoSaveLayer {
public:
FML_WARN_UNUSED_RESULT static AutoSaveLayer Create(
const PaintContext& paint_context,
const SkRect& bounds,
const SkPaint* paint);
[[nodiscard]] static AutoSaveLayer Create(const PaintContext& paint_context,
const SkRect& bounds,
const SkPaint* paint);
FML_WARN_UNUSED_RESULT static AutoSaveLayer Create(
[[nodiscard]] static AutoSaveLayer Create(
const PaintContext& paint_context,
const SkCanvas::SaveLayerRec& layer_rec);
......
......@@ -162,9 +162,8 @@ class SceneUpdateContext {
// CPU wait. Once Vulkan semaphores are available, this method must return
// void and the implementation must submit surfaces on its own as soon as the
// specific canvas operations are done.
FML_WARN_UNUSED_RESULT
std::vector<std::unique_ptr<SurfaceProducerSurface>> ExecutePaintTasks(
CompositorContext::ScopedFrame& frame);
[[nodiscard]] std::vector<std::unique_ptr<SurfaceProducerSurface>>
ExecutePaintTasks(CompositorContext::ScopedFrame& frame);
float ScaleX() const { return metrics_->scale_x * top_scale_x_; }
float ScaleY() const { return metrics_->scale_y * top_scale_y_; }
......
......@@ -54,16 +54,6 @@
#define FML_ALIGNOF(type) __alignof(type)
#endif
// Annotate a function indicating the caller must examine the return value.
// Use like:
// int foo() FML_WARN_UNUSED_RESULT;
// To explicitly ignore a result, see |ignore_result()| in base/macros.h.
#if defined(__GNUC__) || defined(__clang__)
#define FML_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
#else
#define FML_WARN_UNUSED_RESULT
#endif
// Tell the compiler a function is using a printf-style format string.
// |format_param| is the one-based index of the format string parameter;
// |dots_param| is the one-based index of the "..." parameter.
......
......@@ -87,7 +87,7 @@ class Message {
template <typename T,
typename = std::enable_if_t<std::is_trivially_copyable<T>::value>>
FML_WARN_UNUSED_RESULT bool Encode(const T& value) {
[[nodiscard]] bool Encode(const T& value) {
if (auto* buffer = PrepareEncode(sizeof(T))) {
::memcpy(buffer, &value, sizeof(T));
return true;
......@@ -95,7 +95,7 @@ class Message {
return false;
}
FML_WARN_UNUSED_RESULT bool Encode(const MessageSerializable& value) {
[[nodiscard]] bool Encode(const MessageSerializable& value) {
return value.Serialize(*this);
}
......@@ -103,7 +103,7 @@ class Message {
typename T,
typename = std::enable_if_t<
std::is_base_of<MessageSerializable, T>::value>>
FML_WARN_UNUSED_RESULT bool Encode(const std::unique_ptr<T>& value) {
[[nodiscard]] bool Encode(const std::unique_ptr<T>& value) {
// Encode if null.
if (!Encode(static_cast<bool>(value))) {
return false;
......@@ -130,7 +130,7 @@ class Message {
template <typename T,
typename = std::enable_if_t<std::is_trivially_copyable<T>::value>>
FML_WARN_UNUSED_RESULT bool Decode(T& value) {
[[nodiscard]] bool Decode(T& value) {
if (auto* buffer = PrepareDecode(sizeof(T))) {
::memcpy(&value, buffer, sizeof(T));
return true;
......@@ -138,7 +138,7 @@ class Message {
return false;
}
FML_WARN_UNUSED_RESULT bool Decode(MessageSerializable& value) {
[[nodiscard]] bool Decode(MessageSerializable& value) {
return value.Deserialize(*this);
}
......@@ -146,7 +146,7 @@ class Message {
typename T,
typename = std::enable_if_t<
std::is_base_of<MessageSerializable, T>::value>>
FML_WARN_UNUSED_RESULT bool Decode(std::unique_ptr<T>& value) {
[[nodiscard]] bool Decode(std::unique_ptr<T>& value) {
// Decode if null.
bool is_null = false;
if (!Decode(is_null)) {
......@@ -184,17 +184,13 @@ class Message {
size_t data_length_ = 0;
size_t size_read_ = 0;
FML_WARN_UNUSED_RESULT
bool Reserve(size_t size);
[[nodiscard]] bool Reserve(size_t size);
FML_WARN_UNUSED_RESULT
bool Resize(size_t size);
[[nodiscard]] bool Resize(size_t size);
FML_WARN_UNUSED_RESULT
uint8_t* PrepareEncode(size_t size);
[[nodiscard]] uint8_t* PrepareEncode(size_t size);
FML_WARN_UNUSED_RESULT
uint8_t* PrepareDecode(size_t size);
[[nodiscard]] uint8_t* PrepareDecode(size_t size);
FML_DISALLOW_COPY_AND_ASSIGN(Message);
};
......
......@@ -72,7 +72,7 @@ class ScopedBlock {
block_ = temp;
}
B release() FML_WARN_UNUSED_RESULT {
[[nodiscard]] B release() {
B temp = block_;
block_ = nullptr;
return temp;
......
......@@ -79,7 +79,7 @@ class scoped_nsprotocol {
// scoped_nsprotocol<>::release() is like scoped_ptr<>::release. It is NOT a
// wrapper for [object_ release]. To force a scoped_nsprotocol<> to call
// [object_ release], use scoped_nsprotocol<>::reset().
NST release() FML_WARN_UNUSED_RESULT {
[[nodiscard]] NST release() {
NST temp = object_;
object_ = nil;
return temp;
......
......@@ -22,8 +22,7 @@ class Semaphore {
bool IsValid() const;
FML_WARN_UNUSED_RESULT
bool TryWait();
[[nodiscard]] bool TryWait();
void Signal();
......
......@@ -78,7 +78,7 @@ class UniqueObject {
// Release the object. The return value is the current object held by this
// object. After this operation, this object will hold an invalid value, and
// will not own the object any more.
T release() FML_WARN_UNUSED_RESULT {
[[nodiscard]] T release() {
T old_generic = data_.generic;
data_.generic = Traits::InvalidValue();
return old_generic;
......
......@@ -338,8 +338,7 @@ bool DartIsolate::LoadKernel(std::shared_ptr<const fml::Mapping> mapping,
return true;
}
FML_WARN_UNUSED_RESULT
bool DartIsolate::PrepareForRunningFromKernel(
[[nodiscard]] bool DartIsolate::PrepareForRunningFromKernel(
std::shared_ptr<const fml::Mapping> mapping,
bool last_piece) {
TRACE_EVENT0("flutter", "DartIsolate::PrepareForRunningFromKernel");
......@@ -405,8 +404,7 @@ bool DartIsolate::PrepareForRunningFromKernel(
return true;
}
FML_WARN_UNUSED_RESULT
bool DartIsolate::PrepareForRunningFromKernels(
[[nodiscard]] bool DartIsolate::PrepareForRunningFromKernels(
std::vector<std::shared_ptr<const fml::Mapping>> kernels) {
const auto count = kernels.size();
if (count == 0) {
......@@ -423,8 +421,7 @@ bool DartIsolate::PrepareForRunningFromKernels(
return true;
}
FML_WARN_UNUSED_RESULT
bool DartIsolate::PrepareForRunningFromKernels(
[[nodiscard]] bool DartIsolate::PrepareForRunningFromKernels(
std::vector<std::unique_ptr<const fml::Mapping>> kernels) {
std::vector<std::shared_ptr<const fml::Mapping>> shared_kernels;
for (auto& kernel : kernels) {
......@@ -460,9 +457,9 @@ bool DartIsolate::MarkIsolateRunnable() {
return true;
}
FML_WARN_UNUSED_RESULT
static bool InvokeMainEntrypoint(Dart_Handle user_entrypoint_function,
Dart_Handle args) {
[[nodiscard]] static bool InvokeMainEntrypoint(
Dart_Handle user_entrypoint_function,
Dart_Handle args) {
if (tonic::LogIfError(user_entrypoint_function)) {
FML_LOG(ERROR) << "Could not resolve main entrypoint function.";
return false;
......@@ -488,10 +485,9 @@ static bool InvokeMainEntrypoint(Dart_Handle user_entrypoint_function,
}
/// @note Procedure doesn't copy all closures.
FML_WARN_UNUSED_RESULT
bool DartIsolate::Run(const std::string& entrypoint_name,
const std::vector<std::string>& args,
const fml::closure& on_run) {
[[nodiscard]] bool DartIsolate::Run(const std::string& entrypoint_name,
const std::vector<std::string>& args,
const fml::closure& on_run) {
TRACE_EVENT0("flutter", "DartIsolate::Run");
if (phase_ != Phase::Ready) {
return false;
......@@ -517,11 +513,11 @@ bool DartIsolate::Run(const std::string& entrypoint_name,
}
/// @note Procedure doesn't copy all closures.
FML_WARN_UNUSED_RESULT
bool DartIsolate::RunFromLibrary(const std::string& library_name,
const std::string& entrypoint_name,
const std::vector<std::string>& args,
const fml::closure& on_run) {
[[nodiscard]] bool DartIsolate::RunFromLibrary(
const std::string& library_name,
const std::string& entrypoint_name,
const std::vector<std::string>& args,
const fml::closure& on_run) {
TRACE_EVENT0("flutter", "DartIsolate::RunFromLibrary");
if (phase_ != Phase::Ready) {
return false;
......
......@@ -241,8 +241,7 @@ class DartIsolate : public UIDartState {
/// @return Whether the isolate was prepared and the described phase
/// transition made.
///
FML_WARN_UNUSED_RESULT
bool PrepareForRunningFromPrecompiledCode();
[[nodiscard]] bool PrepareForRunningFromPrecompiledCode();
//----------------------------------------------------------------------------
/// @brief Prepare the isolate for running for a a list of kernel files.
......@@ -265,9 +264,9 @@ class DartIsolate : public UIDartState {
/// @return If the kernel mapping supplied was successfully used to
/// prepare the isolate.
///
FML_WARN_UNUSED_RESULT
bool PrepareForRunningFromKernel(std::shared_ptr<const fml::Mapping> kernel,
bool last_piece = true);
[[nodiscard]] bool PrepareForRunningFromKernel(
std::shared_ptr<const fml::Mapping> kernel,
bool last_piece = true);
//----------------------------------------------------------------------------
/// @brief Prepare the isolate for running for a a list of kernel files.
......@@ -284,8 +283,7 @@ class DartIsolate : public UIDartState {
/// @return If the kernel mappings supplied were successfully used to
/// prepare the isolate.
///
FML_WARN_UNUSED_RESULT
bool PrepareForRunningFromKernels(
[[nodiscard]] bool PrepareForRunningFromKernels(
std::vector<std::shared_ptr<const fml::Mapping>> kernels);
//----------------------------------------------------------------------------
......@@ -303,8 +301,7 @@ class DartIsolate : public UIDartState {
/// @return If the kernel mappings supplied were successfully used to
/// prepare the isolate.
///
FML_WARN_UNUSED_RESULT
bool PrepareForRunningFromKernels(
[[nodiscard]] bool PrepareForRunningFromKernels(
std::vector<std::unique_ptr<const fml::Mapping>> kernels);
//----------------------------------------------------------------------------
......@@ -323,10 +320,9 @@ class DartIsolate : public UIDartState {
/// @return If the isolate successfully transitioned to the running phase
/// and the main entrypoint was invoked.
///
FML_WARN_UNUSED_RESULT
bool Run(const std::string& entrypoint,
const std::vector<std::string>& args,
const fml::closure& on_run = nullptr);
[[nodiscard]] bool Run(const std::string& entrypoint,
const std::vector<std::string>& args,
const fml::closure& on_run = nullptr);
//----------------------------------------------------------------------------
/// @brief Transition the root isolate to the `Phase::Running` phase and
......@@ -346,11 +342,10 @@ class DartIsolate : public UIDartState {
/// @return If the isolate successfully transitioned to the running phase
/// and the main entrypoint was invoked.
///
FML_WARN_UNUSED_RESULT
bool RunFromLibrary(const std::string& library_name,
const std::string& entrypoint,
const std::vector<std::string>& args,
const fml::closure& on_run = nullptr);
[[nodiscard]] bool RunFromLibrary(const std::string& library_name,
const std::string& entrypoint,
const std::vector<std::string>& args,
const fml::closure& on_run = nullptr);
//----------------------------------------------------------------------------
/// @brief Transition the isolate to the `Phase::Shutdown` phase. The
......@@ -358,8 +353,7 @@ class DartIsolate : public UIDartState {
///
/// @return If the isolate succesfully transitioned to the shutdown phase.
///
FML_WARN_UNUSED_RESULT
bool Shutdown();
[[nodiscard]] bool Shutdown();
//----------------------------------------------------------------------------
/// @brief Registers a callback that will be invoked in isolate scope
......@@ -418,19 +412,17 @@ class DartIsolate : public UIDartState {
std::string advisory_script_uri,
std::string advisory_script_entrypoint,
bool is_root_isolate);
FML_WARN_UNUSED_RESULT bool Initialize(Dart_Isolate isolate);
[[nodiscard]] bool Initialize(Dart_Isolate isolate);
void SetMessageHandlingTaskRunner(fml::RefPtr<fml::TaskRunner> runner);
bool LoadKernel(std::shared_ptr<const fml::Mapping> mapping, bool last_piece);
FML_WARN_UNUSED_RESULT
bool LoadLibraries();
[[nodiscard]] bool LoadLibraries();
bool UpdateThreadPoolNames() const;
FML_WARN_UNUSED_RESULT
bool MarkIsolateRunnable();
[[nodiscard]] bool MarkIsolateRunnable();
void OnShutdownCallback();
......
......@@ -33,8 +33,7 @@ class DartServiceIsolate {
// Returns a handle for the callback that can be used in
// RemoveServerStatusCallback
FML_WARN_UNUSED_RESULT
static CallbackHandle AddServerStatusCallback(
[[nodiscard]] static CallbackHandle AddServerStatusCallback(
const ObservatoryServerStateCallback& callback);
// Accepts the handle returned by AddServerStatusCallback
......
......@@ -26,10 +26,10 @@ namespace flutter {
// DartVMRef instances may be created on any thread.
class DartVMRef {
public:
FML_WARN_UNUSED_RESULT
static DartVMRef Create(Settings settings,
fml::RefPtr<DartSnapshot> vm_snapshot = nullptr,
fml::RefPtr<DartSnapshot> isolate_snapshot = nullptr);
[[nodiscard]] static DartVMRef Create(
Settings settings,
fml::RefPtr<DartSnapshot> vm_snapshot = nullptr,
fml::RefPtr<DartSnapshot> isolate_snapshot = nullptr);
DartVMRef(DartVMRef&&);
......
......@@ -146,8 +146,7 @@ bool ServiceProtocol::HandleMessage(std::string_view method,
return service_protocol->HandleMessage(method, params, response);
}
FML_WARN_UNUSED_RESULT
static bool HandleMessageOnHandler(
[[nodiscard]] static bool HandleMessageOnHandler(
ServiceProtocol::Handler* handler,
std::string_view method,
const ServiceProtocol::Handler::ServiceProtocolMap& params,
......
......@@ -76,25 +76,22 @@ class ServiceProtocol {
std::unique_ptr<fml::SharedMutex> handlers_mutex_;
std::map<Handler*, fml::AtomicObject<Handler::Description>> handlers_;
FML_WARN_UNUSED_RESULT
static bool HandleMessage(const char* method,
const char** param_keys,
const char** param_values,
intptr_t num_params,
void* user_data,
const char** json_object);
FML_WARN_UNUSED_RESULT
static bool HandleMessage(std::string_view method,
const Handler::ServiceProtocolMap& params,
ServiceProtocol* service_protocol,
rapidjson::Document& response);
FML_WARN_UNUSED_RESULT
bool HandleMessage(std::string_view method,
const Handler::ServiceProtocolMap& params,
rapidjson::Document& response) const;
FML_WARN_UNUSED_RESULT
bool HandleListViewsMethod(rapidjson::Document& response) const;
[[nodiscard]] static bool HandleMessage(const char* method,
const char** param_keys,
const char** param_values,
intptr_t num_params,
void* user_data,
const char** json_object);
[[nodiscard]] static bool HandleMessage(
std::string_view method,
const Handler::ServiceProtocolMap& params,
ServiceProtocol* service_protocol,
rapidjson::Document& response);
[[nodiscard]] bool HandleMessage(std::string_view method,
const Handler::ServiceProtocolMap& params,
rapidjson::Document& response) const;
[[nodiscard]] bool HandleListViewsMethod(rapidjson::Document& response) const;
FML_DISALLOW_COPY_AND_ASSIGN(ServiceProtocol);
};
......
......@@ -342,8 +342,7 @@ class Engine final : public RuntimeDelegate, PointerDataDispatcher::Delegate {
///
/// @return The result of the call to run the root isolate.
///
FML_WARN_UNUSED_RESULT
RunStatus Run(RunConfiguration configuration);
[[nodiscard]] RunStatus Run(RunConfiguration configuration);
//----------------------------------------------------------------------------
/// @brief Tears down an existing root isolate, reuses the components of
......@@ -362,8 +361,7 @@ class Engine final : public RuntimeDelegate, PointerDataDispatcher::Delegate {
/// @return Whether the restart was successful. If not, the engine and its
/// shell must be discarded.
///
FML_WARN_UNUSED_RESULT
bool Restart(RunConfiguration configuration);
[[nodiscard]] bool Restart(RunConfiguration configuration);
//----------------------------------------------------------------------------
/// @brief Updates the asset manager referenced by the root isolate of a
......
......@@ -128,8 +128,7 @@ class Pipeline : public fml::RefCountedThreadSafe<Pipeline<R>> {
using Consumer = std::function<void(ResourcePtr)>;
/// @note Procedure doesn't copy all closures.
FML_WARN_UNUSED_RESULT
PipelineConsumeResult Consume(const Consumer& consumer) {
[[nodiscard]] PipelineConsumeResult Consume(const Consumer& consumer) {
if (consumer == nullptr) {
return PipelineConsumeResult::NoneAvailable;
}
......
......@@ -26,8 +26,8 @@ AutoIsolateShutdown::~AutoIsolateShutdown() {
latch.Wait();
}
FML_WARN_UNUSED_RESULT
bool AutoIsolateShutdown::RunInIsolateScope(std::function<bool(void)> closure) {
[[nodiscard]] bool AutoIsolateShutdown::RunInIsolateScope(
std::function<bool(void)> closure) {
if (!IsValid()) {
return false;
}
......
......@@ -28,8 +28,7 @@ class AutoIsolateShutdown {
bool IsValid() const { return isolate_ != nullptr && runner_; }
FML_WARN_UNUSED_RESULT
bool RunInIsolateScope(std::function<bool(void)> closure);
[[nodiscard]] bool RunInIsolateScope(std::function<bool(void)> closure);
DartIsolate* get() {
FML_CHECK(isolate_);
......
......@@ -26,11 +26,9 @@ class VulkanBackbuffer {
bool IsValid() const;
FML_WARN_UNUSED_RESULT
bool WaitFences();
[[nodiscard]] bool WaitFences();
FML_WARN_UNUSED_RESULT
bool ResetFences();
[[nodiscard]] bool ResetFences();
const VulkanHandle<VkFence>& GetUsageFence() const;
......
......@@ -25,14 +25,11 @@ class VulkanCommandBuffer {
VkCommandBuffer Handle() const;
FML_WARN_UNUSED_RESULT
bool Begin() const;
[[nodiscard]] bool Begin() const;
FML_WARN_UNUSED_RESULT
bool End() const;
[[nodiscard]] bool End() const;
FML_WARN_UNUSED_RESULT
bool InsertPipelineBarrier(
[[nodiscard]] bool InsertPipelineBarrier(
VkPipelineStageFlagBits src_stage_flags,
VkPipelineStageFlagBits dest_stage_flags,
uint32_t /* mask of VkDependencyFlagBits */ dependency_flags,
......
......@@ -37,35 +37,31 @@ class VulkanDevice {
void ReleaseDeviceOwnership();
FML_WARN_UNUSED_RESULT
bool GetSurfaceCapabilities(const VulkanSurface& surface,
VkSurfaceCapabilitiesKHR* capabilities) const;
[[nodiscard]] bool GetSurfaceCapabilities(
const VulkanSurface& surface,
VkSurfaceCapabilitiesKHR* capabilities) const;
FML_WARN_UNUSED_RESULT
bool GetPhysicalDeviceFeatures(VkPhysicalDeviceFeatures* features) const;
[[nodiscard]] bool GetPhysicalDeviceFeatures(
VkPhysicalDeviceFeatures* features) const;
FML_WARN_UNUSED_RESULT
bool GetPhysicalDeviceFeaturesSkia(
[[nodiscard]] bool GetPhysicalDeviceFeaturesSkia(
uint32_t* /* mask of GrVkFeatureFlags */ features) const;
FML_WARN_UNUSED_RESULT
int ChooseSurfaceFormat(const VulkanSurface& surface,
std::vector<VkFormat> desired_formats,
VkSurfaceFormatKHR* format) const;
[[nodiscard]] int ChooseSurfaceFormat(const VulkanSurface& surface,
std::vector<VkFormat> desired_formats,
VkSurfaceFormatKHR* format) const;
FML_WARN_UNUSED_RESULT
bool ChoosePresentMode(const VulkanSurface& surface,
VkPresentModeKHR* present_mode) const;
[[nodiscard]] bool ChoosePresentMode(const VulkanSurface& surface,
VkPresentModeKHR* present_mode) const;
FML_WARN_UNUSED_RESULT
bool QueueSubmit(std::vector<VkPipelineStageFlags> wait_dest_pipeline_stages,
const std::vector<VkSemaphore>& wait_semaphores,
const std::vector<VkSemaphore>& signal_semaphores,
const std::vector<VkCommandBuffer>& command_buffers,
const VulkanHandle<VkFence>& fence) const;
[[nodiscard]] bool QueueSubmit(
std::vector<VkPipelineStageFlags> wait_dest_pipeline_stages,
const std::vector<VkSemaphore>& wait_semaphores,
const std::vector<VkSemaphore>& signal_semaphores,
const std::vector<VkCommandBuffer>& command_buffers,
const VulkanHandle<VkFence>& fence) const;
FML_WARN_UNUSED_RESULT
bool WaitIdle() const;
[[nodiscard]] bool WaitIdle() const;
private:
VulkanProcTable& vk;
......
......@@ -22,12 +22,12 @@ class VulkanImage {
bool IsValid() const;
FML_WARN_UNUSED_RESULT
bool InsertImageMemoryBarrier(const VulkanCommandBuffer& command_buffer,
VkPipelineStageFlagBits src_pipline_bits,
VkPipelineStageFlagBits dest_pipline_bits,
VkAccessFlagBits dest_access_flags,
VkImageLayout dest_layout);
[[nodiscard]] bool InsertImageMemoryBarrier(
const VulkanCommandBuffer& command_buffer,
VkPipelineStageFlagBits src_pipline_bits,
VkPipelineStageFlagBits dest_pipline_bits,
VkAccessFlagBits dest_access_flags,
VkImageLayout dest_layout);
private:
VulkanHandle<VkImage> handle_;
......
......@@ -56,8 +56,7 @@ class VulkanSwapchain {
/// Submit a previously acquired. There must not be consecutive calls to
/// |Submit| without and interleaving |AcquireFrame|.
FML_WARN_UNUSED_RESULT
bool Submit();
[[nodiscard]] bool Submit();
SkISize GetSize() const;
......
......@@ -58,8 +58,7 @@ class VulkanWindow {
bool CreateSkiaBackendContext(GrVkBackendContext* context);
FML_WARN_UNUSED_RESULT
bool RecreateSwapchain();
[[nodiscard]] bool RecreateSwapchain();
FML_DISALLOW_COPY_AND_ASSIGN(VulkanWindow);
};
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册