// Copyright (c) Wojciech Figat. All rights reserved.
#pragma once
#include "GPUResource.h"
#include "PixelFormat.h"
#include "Engine/Platform/Window.h"
class GPUContext;
class GPUTexture;
class GPUTextureView;
class Task;
///
/// GPU swap chain object that provides rendering to native window backbuffer.
///
class FLAXENGINE_API GPUSwapChain : public GPUResource
{
protected:
int32 _width = 0;
int32 _height = 0;
uint64 _presentCount = 0;
PixelFormat _format = PixelFormat::Unknown;
Window* _window = nullptr;
Task* _downloadTask = nullptr;
GPUSwapChain();
public:
///
/// Gets the linked window.
///
Window* GetWindow() const
{
return _window;
}
///
/// The output backbuffer width (in pixels).
///
FORCE_INLINE int32 GetWidth() const
{
return _width;
}
///
/// The output backbuffer height (in pixels).
///
FORCE_INLINE int32 GetHeight() const
{
return _height;
}
///
/// The output backbuffer surface format.
///
FORCE_INLINE PixelFormat GetFormat() const
{
return _format;
}
///
/// The output backbuffer width and height (in pixels).
///
FORCE_INLINE Float2 GetSize() const
{
return Float2(static_cast(_width), static_cast(_height));
}
///
/// The output backbuffer aspect ratio.
///
FORCE_INLINE float GetAspectRatio() const
{
return static_cast(_width) / _height;
}
///
/// Gets amount of backbuffer swaps.
///
FORCE_INLINE uint64 GetPresentCount() const
{
return _presentCount;
}
///
/// True if running in fullscreen mode.
///
/// True if is in fullscreen mode, otherwise false
virtual bool IsFullscreen() = 0;
///
/// Set the fullscreen state.
///
/// Fullscreen mode to apply
virtual void SetFullscreen(bool isFullscreen) = 0;
///
/// Gets the view for the output back buffer texture (for the current frame rendering).
///
/// The output texture view to use.
virtual GPUTextureView* GetBackBufferView() = 0;
///
/// Copies the backbuffer contents to the destination texture.
///
/// The GPU commands context.
/// The destination texture. It must match the output dimensions and format. No staging texture support.
virtual void CopyBackbuffer(GPUContext* context, GPUTexture* dst) = 0;
///
/// Checks if task is ready to render.
///
/// True if is ready, otherwise false
virtual bool IsReady() const
{
// Skip rendering for the hidden windows
return GetWidth() > 0 && (_window->IsVisible() || _window->_showAfterFirstPaint);
}
public:
///
/// Creates GPU async task that will gather render target data from the GPU.
///
/// Result data
/// Download data task (not started yet)
virtual Task* DownloadDataAsync(TextureData& result);
public:
///
/// Begin task rendering.
///
/// Active task
virtual void Begin(RenderTask* task)
{
}
///
/// End task rendering.
///
/// Active task
virtual void End(RenderTask* task);
///
/// Present back buffer to the output.
///
/// True if use vertical synchronization to lock frame rate.
virtual void Present(bool vsync);
///
/// Resize output back buffer.
///
/// New output width (in pixels).
/// New output height (in pixels).
/// True if cannot resize the buffers, otherwise false.
virtual bool Resize(int32 width, int32 height) = 0;
public:
// [GPUResource]
String ToString() const override;
GPUResourceType GetResourceType() const final override;
};