Skip to content

Commit

Permalink
WebView: Refactor AwDrawFnImpl
Browse files Browse the repository at this point in the history
This CL refactors AwDrawFnImpl and creates AwVulkanContextProvider which
will be used to share vulkan objects with SkiaRenderer.

Bug: 939842
Change-Id: I6c8f4a628ea5e3f8b8cb26aaa902cdb3cb484fee
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1512132
Commit-Queue: Peng Huang <[email protected]>
Reviewed-by: Eric Karl <[email protected]>
Cr-Commit-Position: refs/heads/master@{#639729}
  • Loading branch information
phuang authored and Commit Bot committed Mar 12, 2019
1 parent 8e88800 commit bcf31dc
Show file tree
Hide file tree
Showing 12 changed files with 369 additions and 194 deletions.
2 changes: 2 additions & 0 deletions android_webview/browser/gfx/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ source_set("gfx") {
"aw_picture.h",
"aw_render_thread_context_provider.cc",
"aw_render_thread_context_provider.h",
"aw_vulkan_context_provider.cc",
"aw_vulkan_context_provider.h",
"browser_view_renderer.cc",
"browser_view_renderer.h",
"browser_view_renderer_client.h",
Expand Down
229 changes: 56 additions & 173 deletions android_webview/browser/gfx/aw_draw_fn_impl.cc

Large diffs are not rendered by default.

20 changes: 10 additions & 10 deletions android_webview/browser/gfx/aw_draw_fn_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,14 @@
#ifndef ANDROID_WEBVIEW_BROWSER_GFX_AW_DRAW_FN_IMPL_H_
#define ANDROID_WEBVIEW_BROWSER_GFX_AW_DRAW_FN_IMPL_H_

#include <deque>

#include "android_webview/browser/gfx/compositor_frame_consumer.h"
#include "android_webview/browser/gfx/render_thread_manager.h"
#include "android_webview/public/browser/draw_fn.h"
#include "base/android/jni_weak_ref.h"
#include "gpu/vulkan/init/vulkan_factory.h"
#include "base/containers/queue.h"
#include "base/macros.h"
#include "third_party/skia/include/core/SkRefCnt.h"
#include "third_party/skia/include/gpu/vk/GrVkTypes.h"
#include "third_party/vulkan/include/vulkan/vulkan.h"

class GrVkSecondaryCBDrawContext;

Expand All @@ -24,7 +22,7 @@ class GLImageAHardwareBuffer;

namespace android_webview {
class GLNonOwnedCompatibilityContext;
class VulkanState;
class AwVulkanContextProvider;

class AwDrawFnImpl {
public:
Expand All @@ -50,7 +48,7 @@ class AwDrawFnImpl {
private:
// Struct which represents one in-flight draw for the Vk interop path.
struct InFlightDraw {
explicit InFlightDraw(VulkanState* vk_state);
explicit InFlightDraw(AwVulkanContextProvider* vk_context_provider);
~InFlightDraw();
sk_sp<GrVkSecondaryCBDrawContext> draw_context;
VkFence post_draw_fence = VK_NULL_HANDLE;
Expand All @@ -63,7 +61,7 @@ class AwDrawFnImpl {
GrVkImageInfo image_info;

// Used to clean up Vulkan objects.
VulkanState* vk_state;
AwVulkanContextProvider* vk_context_provider;
};

CompositorFrameConsumer* GetCompositorFrameConsumer() {
Expand All @@ -75,15 +73,17 @@ class AwDrawFnImpl {
int functor_handle_;
RenderThreadManager render_thread_manager_;

// State used for Vk rendering.
scoped_refptr<VulkanState> vk_state_;
// Vulkan context provider for Vk rendering.
scoped_refptr<AwVulkanContextProvider> vulkan_context_provider_;

// GL context used to draw via GL in Vk interop path.
scoped_refptr<GLNonOwnedCompatibilityContext> gl_context_;

// Queue of draw contexts pending cleanup.
std::deque<std::unique_ptr<InFlightDraw>> in_flight_draws_;
base::queue<std::unique_ptr<InFlightDraw>> in_flight_draws_;
std::unique_ptr<InFlightDraw> pending_draw_;

DISALLOW_COPY_AND_ASSIGN(AwDrawFnImpl);
};

} // namespace android_webview
Expand Down
159 changes: 159 additions & 0 deletions android_webview/browser/gfx/aw_vulkan_context_provider.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
// Copyright 2019 The Chromium 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 "android_webview/browser/gfx/aw_vulkan_context_provider.h"

#include <utility>

#include "android_webview/public/browser/draw_fn.h"
#include "base/files/file_path.h"
#include "base/native_library.h"
#include "gpu/vulkan/init/vulkan_factory.h"
#include "gpu/vulkan/vulkan_device_queue.h"
#include "gpu/vulkan/vulkan_function_pointers.h"
#include "third_party/skia/include/gpu/GrContext.h"
#include "third_party/skia/include/gpu/vk/GrVkBackendContext.h"
#include "third_party/skia/include/gpu/vk/GrVkExtensions.h"

namespace android_webview {

namespace {

AwVulkanContextProvider* g_vulkan_context_provider = nullptr;

GrVkGetProc MakeUnifiedGetter(const PFN_vkGetInstanceProcAddr& iproc,
const PFN_vkGetDeviceProcAddr& dproc) {
return [&iproc, &dproc](const char* proc_name, VkInstance instance,
VkDevice device) {
if (device != VK_NULL_HANDLE) {
return dproc(device, proc_name);
}
return iproc(instance, proc_name);
};
}

bool InitVulkanForWebView(VkInstance instance, VkDevice device) {
gpu::VulkanFunctionPointers* vulkan_function_pointers =
gpu::GetVulkanFunctionPointers();

// If we are re-initing, we don't need to re-load the shared library or
// re-bind unassociated pointers. These shouldn't change.
if (!vulkan_function_pointers->vulkan_loader_library_) {
base::NativeLibraryLoadError native_library_load_error;
vulkan_function_pointers->vulkan_loader_library_ = base::LoadNativeLibrary(
base::FilePath("libvulkan.so"), &native_library_load_error);
if (!vulkan_function_pointers->vulkan_loader_library_)
return false;
if (!vulkan_function_pointers->BindUnassociatedFunctionPointers())
return false;
}

// These vars depend on |instance| and |device| and should be
// re-initialized.
if (!vulkan_function_pointers->BindInstanceFunctionPointers(instance))
return false;
if (!vulkan_function_pointers->BindPhysicalDeviceFunctionPointers(instance))
return false;
if (!vulkan_function_pointers->BindDeviceFunctionPointers(device))
return false;

return true;
}

} // namespace

// static
scoped_refptr<AwVulkanContextProvider>
AwVulkanContextProvider::GetOrCreateInstance(AwDrawFn_InitVkParams* params) {
if (g_vulkan_context_provider) {
DCHECK_EQ(params->device, g_vulkan_context_provider->device());
DCHECK_EQ(params->queue, g_vulkan_context_provider->queue());
return base::WrapRefCounted(g_vulkan_context_provider);
}

auto provider = base::WrapRefCounted(new AwVulkanContextProvider);
if (!provider->Initialize(params))
return nullptr;

return provider;
}

AwVulkanContextProvider::AwVulkanContextProvider() {
DCHECK_EQ(nullptr, g_vulkan_context_provider);
g_vulkan_context_provider = this;
}

AwVulkanContextProvider::~AwVulkanContextProvider() {
DCHECK_EQ(g_vulkan_context_provider, this);
g_vulkan_context_provider = nullptr;
device_queue_->Destroy();
device_queue_ = nullptr;
}

gpu::VulkanImplementation* AwVulkanContextProvider::GetVulkanImplementation() {
return implementation_.get();
}

gpu::VulkanDeviceQueue* AwVulkanContextProvider::GetDeviceQueue() {
return device_queue_.get();
}

GrContext* AwVulkanContextProvider::GetGrContext() {
return gr_context_.get();
}

GrVkSecondaryCBDrawContext*
AwVulkanContextProvider::GetGrSecondaryCBDrawContext() {
return draw_context_;
}

bool AwVulkanContextProvider::Initialize(AwDrawFn_InitVkParams* params) {
// Don't call init on implementation. Instead call InitVulkanForWebView,
// which avoids creating a new instance.
implementation_ = gpu::CreateVulkanImplementation();
if (!InitVulkanForWebView(params->instance, params->device)) {
LOG(ERROR) << "Unable to initialize Vulkan pointers.";
return false;
}

device_queue_ = std::make_unique<gpu::VulkanDeviceQueue>(params->instance);
gfx::ExtensionSet extensions;
for (uint32_t i = 0; i < params->enabled_device_extension_names_length; ++i)
extensions.insert(params->enabled_device_extension_names[i]);
device_queue_->InitializeForWevbView(
params->physical_device, params->device, params->queue,
params->graphics_queue_index, std::move(extensions));

// Create our Skia GrContext.
GrVkGetProc get_proc =
MakeUnifiedGetter(vkGetInstanceProcAddr, vkGetDeviceProcAddr);
GrVkExtensions vk_extensions;
vk_extensions.init(get_proc, params->instance, params->physical_device,
params->enabled_instance_extension_names_length,
params->enabled_instance_extension_names,
params->enabled_device_extension_names_length,
params->enabled_device_extension_names);
GrVkBackendContext backend_context{
.fInstance = params->instance,
.fPhysicalDevice = params->physical_device,
.fDevice = params->device,
.fQueue = params->queue,
.fGraphicsQueueIndex = params->graphics_queue_index,
.fMaxAPIVersion = params->api_version,
.fVkExtensions = &vk_extensions,
.fDeviceFeatures = params->device_features,
.fDeviceFeatures2 = params->device_features_2,
.fMemoryAllocator = nullptr,
.fGetProc = get_proc,
.fOwnsInstanceAndDevice = false,
};
gr_context_ = GrContext::MakeVulkan(backend_context);
if (!gr_context_) {
LOG(ERROR) << "Unable to initialize GrContext.";
return false;
}
return true;
}

} // namespace android_webview
83 changes: 83 additions & 0 deletions android_webview/browser/gfx/aw_vulkan_context_provider.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// Copyright 2019 The Chromium 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 ANDROID_WEBVIEW_BROWSER_GFX_AW_VULKAN_CONTEXT_PROVIDER_H_
#define ANDROID_WEBVIEW_BROWSER_GFX_AW_VULKAN_CONTEXT_PROVIDER_H_

#include <memory>

#include "base/macros.h"
#include "components/viz/common/gpu/vulkan_context_provider.h"
#include "gpu/vulkan/vulkan_device_queue.h"
#include "third_party/skia/include/core/SkRefCnt.h"

struct AwDrawFn_InitVkParams;
class GrContext;
class GrVkSecondaryCBDrawContext;

namespace gpu {
class VulkanImplementation;
class VulkanDeviceQueue;
} // namespace gpu

namespace android_webview {

class AwVulkanContextProvider final : public viz::VulkanContextProvider {
public:
class ScopedDrawContext {
public:
ScopedDrawContext(AwVulkanContextProvider* provider,
GrVkSecondaryCBDrawContext* draw_context)
: provider_(provider) {
provider_->set_draw_context(draw_context);
}
~ScopedDrawContext() { provider_->set_draw_context(nullptr); }

private:
AwVulkanContextProvider* const provider_;

DISALLOW_COPY_AND_ASSIGN(ScopedDrawContext);
};

static scoped_refptr<AwVulkanContextProvider> GetOrCreateInstance(
AwDrawFn_InitVkParams* params);

// viz::VulkanContextProvider implementation:
gpu::VulkanImplementation* GetVulkanImplementation() override;
gpu::VulkanDeviceQueue* GetDeviceQueue() override;
GrContext* GetGrContext() override;
GrVkSecondaryCBDrawContext* GetGrSecondaryCBDrawContext() override;

VkPhysicalDevice physical_device() {
return device_queue_->GetVulkanPhysicalDevice();
}
VkDevice device() { return device_queue_->GetVulkanDevice(); }
VkQueue queue() { return device_queue_->GetVulkanQueue(); }
gpu::VulkanImplementation* implementation() { return implementation_.get(); }
GrContext* gr_context() { return gr_context_.get(); }

private:
friend class base::RefCounted<AwVulkanContextProvider>;

AwVulkanContextProvider();
~AwVulkanContextProvider() override;

bool Initialize(AwDrawFn_InitVkParams* params);

void set_draw_context(GrVkSecondaryCBDrawContext* draw_context) {
DCHECK_NE(!!draw_context_, !!draw_context);
draw_context_ = draw_context;
}

std::unique_ptr<gpu::VulkanImplementation> implementation_;
std::unique_ptr<gpu::VulkanDeviceQueue> device_queue_;
sk_sp<GrContext> gr_context_;
GrVkSecondaryCBDrawContext* draw_context_ = nullptr;

DISALLOW_COPY_AND_ASSIGN(AwVulkanContextProvider);
};

} // namespace android_webview

#endif // ANDROID_WEBVIEW_BROWSER_GFX_AW_VULKAN_CONTEXT_PROVIDER_H_
2 changes: 2 additions & 0 deletions components/viz/common/gpu/vulkan_context_provider.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "components/viz/common/viz_vulkan_context_provider_export.h"

class GrContext;
class GrVkSecondaryCBDrawContext;

namespace gpu {
class VulkanDeviceQueue;
Expand All @@ -24,6 +25,7 @@ class VIZ_VULKAN_CONTEXT_PROVIDER_EXPORT VulkanContextProvider
virtual gpu::VulkanImplementation* GetVulkanImplementation() = 0;
virtual gpu::VulkanDeviceQueue* GetDeviceQueue() = 0;
virtual GrContext* GetGrContext() = 0;
virtual GrVkSecondaryCBDrawContext* GetGrSecondaryCBDrawContext() = 0;

protected:
friend class base::RefCountedThreadSafe<VulkanContextProvider>;
Expand Down
13 changes: 9 additions & 4 deletions components/viz/common/gpu/vulkan_in_process_context_provider.cc
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,6 @@ void VulkanInProcessContextProvider::Destroy() {
}
}

GrContext* VulkanInProcessContextProvider::GetGrContext() {
return gr_context_.get();
}

gpu::VulkanImplementation*
VulkanInProcessContextProvider::GetVulkanImplementation() {
return vulkan_implementation_;
Expand All @@ -108,6 +104,15 @@ gpu::VulkanDeviceQueue* VulkanInProcessContextProvider::GetDeviceQueue() {
return device_queue_.get();
}

GrContext* VulkanInProcessContextProvider::GetGrContext() {
return gr_context_.get();
}

GrVkSecondaryCBDrawContext*
VulkanInProcessContextProvider::GetGrSecondaryCBDrawContext() {
return nullptr;
}

VulkanInProcessContextProvider::VulkanInProcessContextProvider(
gpu::VulkanImplementation* vulkan_implementation)
: vulkan_implementation_(vulkan_implementation) {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,12 @@ class VIZ_VULKAN_CONTEXT_PROVIDER_EXPORT VulkanInProcessContextProvider

bool Initialize();
void Destroy();
GrContext* GetGrContext() override;

// VulkanContextProvider implementation
gpu::VulkanImplementation* GetVulkanImplementation() override;
gpu::VulkanDeviceQueue* GetDeviceQueue() override;
GrContext* GetGrContext() override;
GrVkSecondaryCBDrawContext* GetGrSecondaryCBDrawContext() override;

protected:
explicit VulkanInProcessContextProvider(
Expand Down
4 changes: 4 additions & 0 deletions gpu/vulkan/generate_bindings.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,10 @@ def GenerateHeaderFile(file, unassociated_functions, instance_functions,
#include <vulkan/vulkan.h>
#if defined(OS_ANDROID)
#include <vulkan/vulkan_android.h>
#endif
#include "base/native_library.h"
#include "build/build_config.h"
#include "gpu/vulkan/vulkan_export.h"
Expand Down
Loading

0 comments on commit bcf31dc

Please sign in to comment.