Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

[Impeller] size vk swapchain to window size. #50205

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion impeller/playground/backend/vulkan/playground_impl_vk.cc
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,11 @@ PlaygroundImplVK::PlaygroundImplVK(PlaygroundSwitches switches)
return;
}

int width = 0;
int height = 0;
::glfwGetWindowSize(window, &width, &height);
size_ = ISize{width, height};

handle_.reset(window);

ContextVK::Settings context_settings;
Expand Down Expand Up @@ -125,7 +130,7 @@ PlaygroundImplVK::PlaygroundImplVK(PlaygroundSwitches switches)

vk::UniqueSurfaceKHR surface{vk_surface, context_vk->GetInstance()};
auto context = context_vk->CreateSurfaceContext();
if (!context->SetWindowSurface(std::move(surface))) {
if (!context->SetWindowSurface(std::move(surface), size_)) {
VALIDATION_LOG << "Could not set up surface for context.";
return;
}
Expand All @@ -150,6 +155,14 @@ std::unique_ptr<Surface> PlaygroundImplVK::AcquireSurfaceFrame(
std::shared_ptr<Context> context) {
SurfaceContextVK* surface_context_vk =
reinterpret_cast<SurfaceContextVK*>(context_.get());

int width = 0;
int height = 0;
::glfwGetWindowSize(reinterpret_cast<GLFWwindow*>(handle_.get()), &width,
&height);
size_ = ISize{width, height};
surface_context_vk->UpdateSurfaceSize(ISize{width, height});

return surface_context_vk->AcquireNextSurface();
}

Expand Down
1 change: 1 addition & 0 deletions impeller/playground/backend/vulkan/playground_impl_vk.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class PlaygroundImplVK final : public PlaygroundImpl {
static void DestroyWindowHandle(WindowHandle handle);
using UniqueHandle = std::unique_ptr<void, decltype(&DestroyWindowHandle)>;
UniqueHandle handle_;
ISize size_ = {1, 1};

// A global Vulkan instance which ensures that the Vulkan library will remain
// loaded throughout the lifetime of the process.
Expand Down
1 change: 1 addition & 0 deletions impeller/renderer/backend/vulkan/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ impeller_component("vulkan_unittests") {
"test/mock_vulkan.cc",
"test/mock_vulkan.h",
"test/mock_vulkan_unittests.cc",
"test/swapchain_unittests.cc",
]
deps = [
":vulkan",
Expand Down
3 changes: 3 additions & 0 deletions impeller/renderer/backend/vulkan/gpu_tracer_vk.cc
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ bool GPUTracerVK::IsEnabled() const {
}

void GPUTracerVK::MarkFrameStart() {
if (!enabled_) {
return;
}
FML_DCHECK(!in_frame_);
in_frame_ = true;
raster_thread_id_ = std::this_thread::get_id();
Expand Down
10 changes: 8 additions & 2 deletions impeller/renderer/backend/vulkan/surface_context_vk.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "impeller/renderer/backend/vulkan/command_pool_vk.h"
#include "impeller/renderer/backend/vulkan/context_vk.h"
#include "impeller/renderer/backend/vulkan/swapchain_vk.h"
#include "impeller/renderer/surface.h"

namespace impeller {

Expand Down Expand Up @@ -61,8 +62,9 @@ void SurfaceContextVK::Shutdown() {
parent_->Shutdown();
}

bool SurfaceContextVK::SetWindowSurface(vk::UniqueSurfaceKHR surface) {
auto swapchain = SwapchainVK::Create(parent_, std::move(surface));
bool SurfaceContextVK::SetWindowSurface(vk::UniqueSurfaceKHR surface,
const ISize& size) {
auto swapchain = SwapchainVK::Create(parent_, std::move(surface), size);
if (!swapchain) {
VALIDATION_LOG << "Could not create swapchain.";
return false;
Expand Down Expand Up @@ -93,6 +95,10 @@ void SurfaceContextVK::SetSyncPresentation(bool value) {
parent_->SetSyncPresentation(value);
}

void SurfaceContextVK::UpdateSurfaceSize(const ISize& size) const {
swapchain_->UpdateSurfaceSize(size);
}

#ifdef FML_OS_ANDROID

vk::UniqueSurfaceKHR SurfaceContextVK::CreateAndroidSurface(
Expand Down
7 changes: 6 additions & 1 deletion impeller/renderer/backend/vulkan/surface_context_vk.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,15 @@ class SurfaceContextVK : public Context,
// |Context|
void SetSyncPresentation(bool value) override;

[[nodiscard]] bool SetWindowSurface(vk::UniqueSurfaceKHR surface);
[[nodiscard]] bool SetWindowSurface(vk::UniqueSurfaceKHR surface,
const ISize& size);

std::unique_ptr<Surface> AcquireNextSurface();

/// @brief Mark the current swapchain configuration as dirty, forcing it to be
/// recreated on the next frame.
void UpdateSurfaceSize(const ISize& size) const;

#ifdef FML_OS_ANDROID
vk::UniqueSurfaceKHR CreateAndroidSurface(ANativeWindow* window) const;
#endif // FML_OS_ANDROID
Expand Down
51 changes: 30 additions & 21 deletions impeller/renderer/backend/vulkan/surface_vk.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include "impeller/renderer/backend/vulkan/surface_vk.h"

#include "impeller/core/formats.h"
#include "impeller/renderer/backend/vulkan/swapchain_image_vk.h"
#include "impeller/renderer/backend/vulkan/texture_vk.h"
#include "impeller/renderer/surface.h"
Expand All @@ -13,30 +14,33 @@ namespace impeller {
std::unique_ptr<SurfaceVK> SurfaceVK::WrapSwapchainImage(
const std::shared_ptr<Context>& context,
std::shared_ptr<SwapchainImageVK>& swapchain_image,
SwapCallback swap_callback) {
SwapCallback swap_callback,
bool enable_msaa) {
if (!context || !swapchain_image || !swap_callback) {
return nullptr;
}

TextureDescriptor msaa_tex_desc;
msaa_tex_desc.storage_mode = StorageMode::kDeviceTransient;
msaa_tex_desc.type = TextureType::kTexture2DMultisample;
msaa_tex_desc.sample_count = SampleCount::kCount4;
msaa_tex_desc.format = swapchain_image->GetPixelFormat();
msaa_tex_desc.size = swapchain_image->GetSize();
msaa_tex_desc.usage = static_cast<uint64_t>(TextureUsage::kRenderTarget);

std::shared_ptr<Texture> msaa_tex;
if (!swapchain_image->HasMSAATexture()) {
msaa_tex = context->GetResourceAllocator()->CreateTexture(msaa_tex_desc);
msaa_tex->SetLabel("ImpellerOnscreenColorMSAA");
if (!msaa_tex) {
VALIDATION_LOG << "Could not allocate MSAA color texture.";
return nullptr;
if (enable_msaa) {
TextureDescriptor msaa_tex_desc;
msaa_tex_desc.storage_mode = StorageMode::kDeviceTransient;
msaa_tex_desc.type = TextureType::kTexture2DMultisample;
msaa_tex_desc.sample_count = SampleCount::kCount4;
msaa_tex_desc.format = swapchain_image->GetPixelFormat();
msaa_tex_desc.size = swapchain_image->GetSize();
msaa_tex_desc.usage = static_cast<uint64_t>(TextureUsage::kRenderTarget);

if (!swapchain_image->HasMSAATexture()) {
msaa_tex = context->GetResourceAllocator()->CreateTexture(msaa_tex_desc);
msaa_tex->SetLabel("ImpellerOnscreenColorMSAA");
if (!msaa_tex) {
VALIDATION_LOG << "Could not allocate MSAA color texture.";
return nullptr;
}
swapchain_image->SetMSAATexture(msaa_tex);
} else {
msaa_tex = swapchain_image->GetMSAATexture();
}
swapchain_image->SetMSAATexture(msaa_tex);
} else {
msaa_tex = swapchain_image->GetMSAATexture();
}

TextureDescriptor resolve_tex_desc;
Expand All @@ -60,11 +64,16 @@ std::unique_ptr<SurfaceVK> SurfaceVK::WrapSwapchainImage(
resolve_tex->SetLabel("ImpellerOnscreenResolve");

ColorAttachment color0;
color0.texture = msaa_tex;
color0.clear_color = Color::DarkSlateGray();
color0.load_action = LoadAction::kClear;
color0.store_action = StoreAction::kMultisampleResolve;
color0.resolve_texture = resolve_tex;
if (enable_msaa) {
color0.texture = msaa_tex;
color0.store_action = StoreAction::kMultisampleResolve;
color0.resolve_texture = resolve_tex;
} else {
color0.texture = resolve_tex;
color0.store_action = StoreAction::kStore;
}

RenderTarget render_target_desc;
render_target_desc.SetColorAttachment(color0, 0u);
Expand Down
3 changes: 2 additions & 1 deletion impeller/renderer/backend/vulkan/surface_vk.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ class SurfaceVK final : public Surface {
static std::unique_ptr<SurfaceVK> WrapSwapchainImage(
const std::shared_ptr<Context>& context,
std::shared_ptr<SwapchainImageVK>& swapchain_image,
SwapCallback swap_callback);
SwapCallback swap_callback,
bool enable_msaa = true);

// |Surface|
~SurfaceVK() override;
Expand Down
1 change: 0 additions & 1 deletion impeller/renderer/backend/vulkan/swapchain_image_vk.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
#ifndef FLUTTER_IMPELLER_RENDERER_BACKEND_VULKAN_SWAPCHAIN_IMAGE_VK_H_
#define FLUTTER_IMPELLER_RENDERER_BACKEND_VULKAN_SWAPCHAIN_IMAGE_VK_H_

#include "flutter/fml/macros.h"
#include "impeller/geometry/size.h"
#include "impeller/renderer/backend/vulkan/formats_vk.h"
#include "impeller/renderer/backend/vulkan/texture_source_vk.h"
Expand Down
55 changes: 19 additions & 36 deletions impeller/renderer/backend/vulkan/swapchain_impl_vk.cc
Original file line number Diff line number Diff line change
Expand Up @@ -145,17 +145,18 @@ static std::optional<vk::Queue> ChoosePresentQueue(
std::shared_ptr<SwapchainImplVK> SwapchainImplVK::Create(
const std::shared_ptr<Context>& context,
vk::UniqueSurfaceKHR surface,
vk::SwapchainKHR old_swapchain,
vk::SurfaceTransformFlagBitsKHR last_transform) {
const ISize& size,
bool enable_msaa,
vk::SwapchainKHR old_swapchain) {
return std::shared_ptr<SwapchainImplVK>(new SwapchainImplVK(
context, std::move(surface), old_swapchain, last_transform));
context, std::move(surface), size, enable_msaa, old_swapchain));
}

SwapchainImplVK::SwapchainImplVK(
const std::shared_ptr<Context>& context,
vk::UniqueSurfaceKHR surface,
vk::SwapchainKHR old_swapchain,
vk::SurfaceTransformFlagBitsKHR last_transform) {
SwapchainImplVK::SwapchainImplVK(const std::shared_ptr<Context>& context,
vk::UniqueSurfaceKHR surface,
const ISize& size,
bool enable_msaa,
vk::SwapchainKHR old_swapchain) {
if (!context) {
VALIDATION_LOG << "Cannot create a swapchain without a context.";
return;
Expand Down Expand Up @@ -209,10 +210,10 @@ SwapchainImplVK::SwapchainImplVK(
swapchain_info.imageColorSpace = format.value().colorSpace;
swapchain_info.presentMode = vk::PresentModeKHR::eFifo;
swapchain_info.imageExtent = vk::Extent2D{
std::clamp(surface_caps.currentExtent.width,
std::clamp(static_cast<uint32_t>(size.width),
surface_caps.minImageExtent.width,
surface_caps.maxImageExtent.width),
std::clamp(surface_caps.currentExtent.height,
std::clamp(static_cast<uint32_t>(size.height),
surface_caps.minImageExtent.height,
surface_caps.maxImageExtent.height),
};
Expand Down Expand Up @@ -304,14 +305,19 @@ SwapchainImplVK::SwapchainImplVK(
images_ = std::move(swapchain_images);
synchronizers_ = std::move(synchronizers);
current_frame_ = synchronizers_.size() - 1u;
size_ = size;
enable_msaa_ = enable_msaa;
is_valid_ = true;
transform_if_changed_discard_swapchain_ = last_transform;
}

SwapchainImplVK::~SwapchainImplVK() {
DestroySwapchain();
}

const ISize& SwapchainImplVK::GetSize() const {
return size_;
}

bool SwapchainImplVK::IsValid() const {
return is_valid_;
}
Expand All @@ -337,10 +343,6 @@ vk::Format SwapchainImplVK::GetSurfaceFormat() const {
return surface_format_;
}

vk::SurfaceTransformFlagBitsKHR SwapchainImplVK::GetLastTransform() const {
return transform_if_changed_discard_swapchain_;
}

std::shared_ptr<Context> SwapchainImplVK::GetContext() const {
return context_.lock();
}
Expand All @@ -365,26 +367,6 @@ SwapchainImplVK::AcquireResult SwapchainImplVK::AcquireNextDrawable() {
return SwapchainImplVK::AcquireResult{};
}

//----------------------------------------------------------------------------
/// Poll to see if the orientation has changed.
///
/// https://developer.android.com/games/optimize/vulkan-prerotation#using_polling
current_transform_poll_count_++;
if (current_transform_poll_count_ >= kPollFramesForOrientation) {
current_transform_poll_count_ = 0u;
auto [caps_result, caps] =
context.GetPhysicalDevice().getSurfaceCapabilitiesKHR(*surface_);
if (caps_result != vk::Result::eSuccess) {
VALIDATION_LOG << "Could not get surface capabilities: "
<< vk::to_string(caps_result);
return SwapchainImplVK::AcquireResult{};
}
if (caps.currentTransform != transform_if_changed_discard_swapchain_) {
transform_if_changed_discard_swapchain_ = caps.currentTransform;
return AcquireResult{true /* out of date */};
}
}

//----------------------------------------------------------------------------
/// Get the next image index.
///
Expand Down Expand Up @@ -430,7 +412,8 @@ SwapchainImplVK::AcquireResult SwapchainImplVK::AcquireNextDrawable() {
return false;
}
return swapchain->Present(image, image_index);
} // swap callback
}, // swap callback
enable_msaa_ //
)};
}

Expand Down
21 changes: 11 additions & 10 deletions impeller/renderer/backend/vulkan/swapchain_impl_vk.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#include <memory>
#include <variant>

#include "flutter/fml/macros.h"
#include "impeller/geometry/size.h"
#include "impeller/renderer/backend/vulkan/vk.h"
#include "vulkan/vulkan_enums.hpp"

Expand All @@ -34,9 +34,9 @@ class SwapchainImplVK final
static std::shared_ptr<SwapchainImplVK> Create(
const std::shared_ptr<Context>& context,
vk::UniqueSurfaceKHR surface,
vk::SwapchainKHR old_swapchain = VK_NULL_HANDLE,
vk::SurfaceTransformFlagBitsKHR last_transform =
vk::SurfaceTransformFlagBitsKHR::eIdentity);
const ISize& size,
bool enable_msaa = true,
vk::SwapchainKHR old_swapchain = VK_NULL_HANDLE);

~SwapchainImplVK();

Expand All @@ -57,12 +57,12 @@ class SwapchainImplVK final

vk::Format GetSurfaceFormat() const;

vk::SurfaceTransformFlagBitsKHR GetLastTransform() const;

std::shared_ptr<Context> GetContext() const;

std::pair<vk::UniqueSurfaceKHR, vk::UniqueSwapchainKHR> DestroySwapchain();

const ISize& GetSize() const;

private:
std::weak_ptr<Context> context_;
vk::UniqueSurfaceKHR surface_;
Expand All @@ -72,14 +72,15 @@ class SwapchainImplVK final
std::vector<std::shared_ptr<SwapchainImageVK>> images_;
std::vector<std::unique_ptr<FrameSynchronizer>> synchronizers_;
size_t current_frame_ = 0u;
ISize size_;
bool enable_msaa_ = true;
bool is_valid_ = false;
size_t current_transform_poll_count_ = 0u;
vk::SurfaceTransformFlagBitsKHR transform_if_changed_discard_swapchain_;

SwapchainImplVK(const std::shared_ptr<Context>& context,
vk::UniqueSurfaceKHR surface,
vk::SwapchainKHR old_swapchain,
vk::SurfaceTransformFlagBitsKHR last_transform);
const ISize& size,
bool enable_msaa,
vk::SwapchainKHR old_swapchain);

bool Present(const std::shared_ptr<SwapchainImageVK>& image, uint32_t index);

Expand Down
Loading