Skip to content

Commit

Permalink
Refactor of Vulkan GPUSurface code (#16224)
Browse files Browse the repository at this point in the history
Co-authored-by: David Worsham <arbreng@gmail.com>
  • Loading branch information
George Wright and arbreng committed Feb 4, 2020
1 parent 8c6cc65 commit 677b563
Show file tree
Hide file tree
Showing 14 changed files with 135 additions and 37 deletions.
2 changes: 2 additions & 0 deletions ci/licenses_golden/licenses_flutter
Expand Up @@ -603,6 +603,8 @@ FILE: ../../../flutter/shell/gpu/gpu_surface_software_delegate.cc
FILE: ../../../flutter/shell/gpu/gpu_surface_software_delegate.h
FILE: ../../../flutter/shell/gpu/gpu_surface_vulkan.cc
FILE: ../../../flutter/shell/gpu/gpu_surface_vulkan.h
FILE: ../../../flutter/shell/gpu/gpu_surface_vulkan_delegate.cc
FILE: ../../../flutter/shell/gpu/gpu_surface_vulkan_delegate.h
FILE: ../../../flutter/shell/platform/android/AndroidManifest.xml
FILE: ../../../flutter/shell/platform/android/android_context_gl.cc
FILE: ../../../flutter/shell/platform/android/android_context_gl.h
Expand Down
4 changes: 4 additions & 0 deletions shell/gpu/BUILD.gn
Expand Up @@ -16,6 +16,7 @@ gpu_common_deps = [

source_set("gpu_surface_software") {
sources = [
"$gpu_dir/gpu_surface_delegate.h",
"$gpu_dir/gpu_surface_software.cc",
"$gpu_dir/gpu_surface_software.h",
"$gpu_dir/gpu_surface_software_delegate.cc",
Expand All @@ -39,8 +40,11 @@ source_set("gpu_surface_gl") {

source_set("gpu_surface_vulkan") {
sources = [
"$gpu_dir/gpu_surface_delegate.h",
"$gpu_dir/gpu_surface_vulkan.cc",
"$gpu_dir/gpu_surface_vulkan.h",
"$gpu_dir/gpu_surface_vulkan_delegate.cc",
"$gpu_dir/gpu_surface_vulkan_delegate.h",
]

deps = gpu_common_deps + [
Expand Down
16 changes: 13 additions & 3 deletions shell/gpu/gpu_surface_delegate.h
Expand Up @@ -2,14 +2,24 @@
#define FLUTTER_SHELL_GPU_GPU_SURFACE_DELEGATE_H_

#include "flutter/flow/embedded_views.h"
#include "flutter/fml/macros.h"

namespace flutter {

class GPUSurfaceDelegate {
public:
// Get a reference to the external views embedder. This happens on the same
// thread that the renderer is operating on.
virtual ~GPUSurfaceDelegate() {}

//----------------------------------------------------------------------------
/// @brief Gets the view embedder that controls how the Flutter layer
/// hierarchy split into multiple chunks should be composited back
/// on-screen. This field is optional and the Flutter rasterizer
/// will render into a single on-screen surface if this call
/// returns a null external view embedder. This happens on the GPU
/// thread.
///
/// @return The external view embedder, or, null if Flutter is rendering
/// into a single on-screen surface.
///
virtual ExternalViewEmbedder* GetExternalViewEmbedder() = 0;
};

Expand Down
6 changes: 6 additions & 0 deletions shell/gpu/gpu_surface_gl_delegate.cc
Expand Up @@ -8,6 +8,8 @@

namespace flutter {

GPUSurfaceGLDelegate::~GPUSurfaceGLDelegate() = default;

bool GPUSurfaceGLDelegate::GLContextFBOResetAfterPresent() const {
return false;
}
Expand Down Expand Up @@ -95,4 +97,8 @@ GPUSurfaceGLDelegate::GetDefaultPlatformGLInterface() {
return CreateGLInterface(nullptr);
}

ExternalViewEmbedder* GPUSurfaceGLDelegate::GetExternalViewEmbedder() {
return nullptr;
}

} // namespace flutter
5 changes: 5 additions & 0 deletions shell/gpu/gpu_surface_gl_delegate.h
Expand Up @@ -15,6 +15,11 @@ namespace flutter {

class GPUSurfaceGLDelegate : public GPUSurfaceDelegate {
public:
~GPUSurfaceGLDelegate() override;

// |GPUSurfaceDelegate|
ExternalViewEmbedder* GetExternalViewEmbedder() override;

// Called to make the main GL context current on the current thread.
virtual bool GLContextMakeCurrent() = 0;

Expand Down
20 changes: 6 additions & 14 deletions shell/gpu/gpu_surface_software_delegate.h
Expand Up @@ -7,6 +7,7 @@

#include "flutter/flow/embedded_views.h"
#include "flutter/fml/macros.h"
#include "flutter/shell/gpu/gpu_surface_delegate.h"
#include "third_party/skia/include/core/SkSurface.h"

namespace flutter {
Expand All @@ -24,9 +25,12 @@ namespace flutter {
/// @see |IOSurfaceSoftware|, |AndroidSurfaceSoftware|,
/// |EmbedderSurfaceSoftware|.
///
class GPUSurfaceSoftwareDelegate {
class GPUSurfaceSoftwareDelegate : public GPUSurfaceDelegate {
public:
virtual ~GPUSurfaceSoftwareDelegate();
~GPUSurfaceSoftwareDelegate() override;

// |GPUSurfaceDelegate|
ExternalViewEmbedder* GetExternalViewEmbedder() override;

//----------------------------------------------------------------------------
/// @brief Called when the GPU surface needs a new buffer to render a new
Expand All @@ -48,18 +52,6 @@ class GPUSurfaceSoftwareDelegate {
/// the screen.
///
virtual bool PresentBackingStore(sk_sp<SkSurface> backing_store) = 0;

//----------------------------------------------------------------------------
/// @brief Gets the view embedder that controls how the Flutter layer
/// hierarchy split into multiple chunks should be composited back
/// on-screen. This field is optional and the Flutter rasterizer
/// will render into a single on-screen surface if this call
/// returns a null external view embedder.
///
/// @return The external view embedder, or, null if Flutter is rendering
/// into a single on-screen surface.
///
virtual ExternalViewEmbedder* GetExternalViewEmbedder() = 0;
};

} // namespace flutter
Expand Down
26 changes: 19 additions & 7 deletions shell/gpu/gpu_surface_vulkan.cc
Expand Up @@ -8,21 +8,31 @@
namespace flutter {

GPUSurfaceVulkan::GPUSurfaceVulkan(
fml::RefPtr<vulkan::VulkanProcTable> proc_table,
std::unique_ptr<vulkan::VulkanNativeSurface> native_surface)
: window_(std::move(proc_table), std::move(native_surface)),
GPUSurfaceVulkanDelegate* delegate,
std::unique_ptr<vulkan::VulkanNativeSurface> native_surface,
bool render_to_surface)
: window_(delegate->vk(), std::move(native_surface), render_to_surface),
delegate_(delegate),
render_to_surface_(render_to_surface),
weak_factory_(this) {}

GPUSurfaceVulkan::~GPUSurfaceVulkan() = default;

// |Surface|
bool GPUSurfaceVulkan::IsValid() {
return window_.IsValid();
}

// |Surface|
std::unique_ptr<SurfaceFrame> GPUSurfaceVulkan::AcquireFrame(
const SkISize& size) {
// TODO(38466): Refactor GPU surface APIs take into account the fact that an
// external view embedder may want to render to the root surface.
if (!render_to_surface_) {
return std::make_unique<SurfaceFrame>(
nullptr, true, [](const SurfaceFrame& surface_frame, SkCanvas* canvas) {
return true;
});
}

auto surface = window_.AcquireSurface();

if (surface == nullptr) {
Expand All @@ -44,7 +54,6 @@ std::unique_ptr<SurfaceFrame> GPUSurfaceVulkan::AcquireFrame(
std::move(callback));
}

// |Surface|
SkMatrix GPUSurfaceVulkan::GetRootTransformation() const {
// This backend does not support delegating to the underlying platform to
// query for root surface transformations. Just return identity.
Expand All @@ -53,9 +62,12 @@ SkMatrix GPUSurfaceVulkan::GetRootTransformation() const {
return matrix;
}

// |Surface|
GrContext* GPUSurfaceVulkan::GetContext() {
return window_.GetSkiaGrContext();
}

flutter::ExternalViewEmbedder* GPUSurfaceVulkan::GetExternalViewEmbedder() {
return delegate_->GetExternalViewEmbedder();
}

} // namespace flutter
12 changes: 10 additions & 2 deletions shell/gpu/gpu_surface_vulkan.h
Expand Up @@ -10,15 +10,17 @@
#include "flutter/fml/macros.h"
#include "flutter/fml/memory/weak_ptr.h"
#include "flutter/shell/common/surface.h"
#include "flutter/shell/gpu/gpu_surface_vulkan_delegate.h"
#include "flutter/vulkan/vulkan_native_surface.h"
#include "flutter/vulkan/vulkan_window.h"

namespace flutter {

class GPUSurfaceVulkan : public Surface {
public:
GPUSurfaceVulkan(fml::RefPtr<vulkan::VulkanProcTable> proc_table,
std::unique_ptr<vulkan::VulkanNativeSurface> native_surface);
GPUSurfaceVulkan(GPUSurfaceVulkanDelegate* delegate,
std::unique_ptr<vulkan::VulkanNativeSurface> native_surface,
bool render_to_surface);

~GPUSurfaceVulkan() override;

Expand All @@ -34,8 +36,14 @@ class GPUSurfaceVulkan : public Surface {
// |Surface|
GrContext* GetContext() override;

// |Surface|
flutter::ExternalViewEmbedder* GetExternalViewEmbedder() override;

private:
vulkan::VulkanWindow window_;
GPUSurfaceVulkanDelegate* delegate_;
const bool render_to_surface_;

fml::WeakPtrFactory<GPUSurfaceVulkan> weak_factory_;

FML_DISALLOW_COPY_AND_ASSIGN(GPUSurfaceVulkan);
Expand Down
15 changes: 15 additions & 0 deletions shell/gpu/gpu_surface_vulkan_delegate.cc
@@ -0,0 +1,15 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "flutter/shell/gpu/gpu_surface_vulkan_delegate.h"

namespace flutter {

GPUSurfaceVulkanDelegate::~GPUSurfaceVulkanDelegate() = default;

ExternalViewEmbedder* GPUSurfaceVulkanDelegate::GetExternalViewEmbedder() {
return nullptr;
}

} // namespace flutter
27 changes: 27 additions & 0 deletions shell/gpu/gpu_surface_vulkan_delegate.h
@@ -0,0 +1,27 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef FLUTTER_SHELL_GPU_GPU_SURFACE_VULKAN_DELEGATE_H_
#define FLUTTER_SHELL_GPU_GPU_SURFACE_VULKAN_DELEGATE_H_

#include "flutter/fml/memory/ref_ptr.h"
#include "flutter/shell/gpu/gpu_surface_delegate.h"
#include "flutter/vulkan/vulkan_proc_table.h"

namespace flutter {

class GPUSurfaceVulkanDelegate : public GPUSurfaceDelegate {
public:
~GPUSurfaceVulkanDelegate() override;

// |GPUSurfaceDelegate|
ExternalViewEmbedder* GetExternalViewEmbedder() override;

// Obtain a reference to the Vulkan implementation's proc table.
virtual fml::RefPtr<vulkan::VulkanProcTable> vk() = 0;
};

} // namespace flutter

#endif // FLUTTER_SHELL_GPU_GPU_SURFACE_VULKAN_DELEGATE_H_
16 changes: 9 additions & 7 deletions shell/platform/android/android_surface_vulkan.cc
Expand Up @@ -21,12 +21,10 @@ bool AndroidSurfaceVulkan::IsValid() const {
return proc_table_->HasAcquiredMandatoryProcAddresses();
}

// |AndroidSurface|
void AndroidSurfaceVulkan::TeardownOnScreenContext() {
// Nothing to do.
}

// |AndroidSurface|
std::unique_ptr<Surface> AndroidSurfaceVulkan::CreateGPUSurface() {
if (!IsValid()) {
return nullptr;
Expand All @@ -45,7 +43,7 @@ std::unique_ptr<Surface> AndroidSurfaceVulkan::CreateGPUSurface() {
}

auto gpu_surface = std::make_unique<GPUSurfaceVulkan>(
proc_table_, std::move(vulkan_surface_android));
this, std::move(vulkan_surface_android), true);

if (!gpu_surface->IsValid()) {
return nullptr;
Expand All @@ -54,28 +52,32 @@ std::unique_ptr<Surface> AndroidSurfaceVulkan::CreateGPUSurface() {
return gpu_surface;
}

// |AndroidSurface|
bool AndroidSurfaceVulkan::OnScreenSurfaceResize(const SkISize& size) const {
return true;
}

// |AndroidSurface|
bool AndroidSurfaceVulkan::ResourceContextMakeCurrent() {
FML_DLOG(ERROR) << "The vulkan backend does not support resource contexts.";
return false;
}

// |AndroidSurface|
bool AndroidSurfaceVulkan::ResourceContextClearCurrent() {
FML_DLOG(ERROR) << "The vulkan backend does not support resource contexts.";
return false;
}

// |AndroidSurface|
bool AndroidSurfaceVulkan::SetNativeWindow(
fml::RefPtr<AndroidNativeWindow> window) {
native_window_ = std::move(window);
return native_window_ && native_window_->IsValid();
}

ExternalViewEmbedder* AndroidSurfaceVulkan::GetExternalViewEmbedder() {
return nullptr;
}

fml::RefPtr<vulkan::VulkanProcTable> AndroidSurfaceVulkan::vk() {
return proc_table_;
}

} // namespace flutter
10 changes: 9 additions & 1 deletion shell/platform/android/android_surface_vulkan.h
Expand Up @@ -8,13 +8,15 @@
#include <jni.h>
#include <memory>
#include "flutter/fml/macros.h"
#include "flutter/shell/gpu/gpu_surface_vulkan_delegate.h"
#include "flutter/shell/platform/android/android_native_window.h"
#include "flutter/shell/platform/android/android_surface.h"
#include "flutter/vulkan/vulkan_window.h"

namespace flutter {

class AndroidSurfaceVulkan : public AndroidSurface {
class AndroidSurfaceVulkan : public AndroidSurface,
public GPUSurfaceVulkanDelegate {
public:
AndroidSurfaceVulkan();

Expand All @@ -41,6 +43,12 @@ class AndroidSurfaceVulkan : public AndroidSurface {
// |AndroidSurface|
bool SetNativeWindow(fml::RefPtr<AndroidNativeWindow> window) override;

// |GPUSurfaceVulkanDelegate|
ExternalViewEmbedder* GetExternalViewEmbedder() override;

// |GPUSurfaceVulkanDelegate|
fml::RefPtr<vulkan::VulkanProcTable> vk() override;

private:
fml::RefPtr<vulkan::VulkanProcTable> proc_table_;
fml::RefPtr<AndroidNativeWindow> native_window_;
Expand Down
10 changes: 8 additions & 2 deletions vulkan/vulkan_window.cc
Expand Up @@ -17,7 +17,8 @@
namespace vulkan {

VulkanWindow::VulkanWindow(fml::RefPtr<VulkanProcTable> proc_table,
std::unique_ptr<VulkanNativeSurface> native_surface)
std::unique_ptr<VulkanNativeSurface> native_surface,
bool render_to_surface)
: valid_(false), vk(std::move(proc_table)) {
if (!vk || !vk->HasAcquiredMandatoryProcAddresses()) {
FML_DLOG(INFO) << "Proc table has not acquired mandatory proc addresses.";
Expand Down Expand Up @@ -58,8 +59,13 @@ VulkanWindow::VulkanWindow(fml::RefPtr<VulkanProcTable> proc_table,
return;
}

// Create the logical surface from the native platform surface.
// TODO(38466): Refactor GPU surface APIs take into account the fact that an
// external view embedder may want to render to the root surface.
if (!render_to_surface) {
return;
}

// Create the logical surface from the native platform surface.
surface_ = std::make_unique<VulkanSurface>(*vk, *application_,
std::move(native_surface));

Expand Down
3 changes: 2 additions & 1 deletion vulkan/vulkan_window.h
Expand Up @@ -32,7 +32,8 @@ class VulkanBackbuffer;
class VulkanWindow {
public:
VulkanWindow(fml::RefPtr<VulkanProcTable> proc_table,
std::unique_ptr<VulkanNativeSurface> native_surface);
std::unique_ptr<VulkanNativeSurface> native_surface,
bool render_to_surface);

~VulkanWindow();

Expand Down

0 comments on commit 677b563

Please sign in to comment.