webnn: wait on coreml cache dir setup
Move Core ML cache directory setup logic to be called on WebNN context creation and let context creation wait on the cache directory setup to be finished. Bug: 344935458 Change-Id: I045d7f644df7d3db0b5985e3b647812919ab820e Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6237277 Reviewed-by: Mark Mentovai <mark@chromium.org> Reviewed-by: Reilly Grant <reillyg@chromium.org> Commit-Queue: Phillis Tang <phillis@chromium.org> Auto-Submit: Phillis Tang <phillis@chromium.org> Reviewed-by: Avi Drissman <avi@chromium.org> Cr-Commit-Position: refs/heads/main@{#1417848}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
a8e8fa1698
commit
4247919d79
content/browser
services/webnn/public/cpp
@ -2786,6 +2786,7 @@ source_set("browser") {
|
||||
"//components/remote_cocoa/browser",
|
||||
"//components/remote_cocoa/common:mojo",
|
||||
"//media",
|
||||
"//services/webnn/public/cpp",
|
||||
"//ui/accelerated_widget_mac",
|
||||
"//ui/events:dom_keyboard_layout",
|
||||
]
|
||||
|
@ -238,6 +238,7 @@
|
||||
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
#include "content/browser/renderer_host/text_input_host_impl.h"
|
||||
#include "services/webnn/public/cpp/coreml_initializer.h"
|
||||
#include "third_party/blink/public/mojom/input/text_input_host.mojom.h"
|
||||
#endif
|
||||
|
||||
@ -304,7 +305,13 @@ void BindWebNNContextProviderForRenderFrame(
|
||||
RenderFrameHost* host,
|
||||
mojo::PendingReceiver<webnn::mojom::WebNNContextProvider> receiver) {
|
||||
auto* process_host = static_cast<RenderProcessHostImpl*>(host->GetProcess());
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
webnn::InitializeCacheDirAndRun(base::BindOnce(
|
||||
&viz::GpuClient::BindWebNNContextProvider,
|
||||
process_host->GetGpuClient()->GetWeakPtr(), std::move(receiver)));
|
||||
#else
|
||||
process_host->GetGpuClient()->BindWebNNContextProvider(std::move(receiver));
|
||||
#endif
|
||||
}
|
||||
|
||||
void BindWebNNContextProviderForDedicatedWorker(
|
||||
@ -312,7 +319,13 @@ void BindWebNNContextProviderForDedicatedWorker(
|
||||
mojo::PendingReceiver<webnn::mojom::WebNNContextProvider> receiver) {
|
||||
auto* process_host =
|
||||
static_cast<RenderProcessHostImpl*>(host->GetProcessHost());
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
webnn::InitializeCacheDirAndRun(base::BindOnce(
|
||||
&viz::GpuClient::BindWebNNContextProvider,
|
||||
process_host->GetGpuClient()->GetWeakPtr(), std::move(receiver)));
|
||||
#else
|
||||
process_host->GetGpuClient()->BindWebNNContextProvider(std::move(receiver));
|
||||
#endif
|
||||
}
|
||||
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
|
@ -127,8 +127,6 @@
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
#include "base/apple/foundation_util.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "content/browser/gpu/browser_child_process_backgrounded_bridge.h"
|
||||
#include "content/browser/gpu/ca_transaction_gpu_coordinator.h"
|
||||
#endif
|
||||
@ -535,25 +533,6 @@ void BindDiscardableMemoryReceiverOnUI(
|
||||
discardable_memory::DiscardableSharedMemoryManager::Get()));
|
||||
}
|
||||
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
// Create cache directory that's needed for WebNN. WebNN underlying uses Apple's
|
||||
// Core ML framework that needs access to this directory. By creating the
|
||||
// directory here we don't need to give the GPU process the ability to create
|
||||
// directories in the sandbox policy.
|
||||
void SetUpCoreMLCacheDir() {
|
||||
base::FilePath cache_dir =
|
||||
base::GetHomeDir()
|
||||
.Append("Library")
|
||||
.Append("Caches")
|
||||
.Append(base::StrCat({base::apple::BaseBundleID(), ".helper"}))
|
||||
.Append("com.apple.e5rt.e5bundlecache");
|
||||
if (!base::CreateDirectory(cache_dir)) {
|
||||
LOG(ERROR) << "Failed to setup cache directory for WebNN, this might "
|
||||
"affect the performance and accuracy for WebNN.";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
// static
|
||||
@ -1238,12 +1217,6 @@ void GpuProcessHost::RunServiceImpl(mojo::GenericPendingReceiver receiver) {
|
||||
}
|
||||
|
||||
bool GpuProcessHost::LaunchGpuProcess() {
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
base::ThreadPool::PostTask(
|
||||
FROM_HERE,
|
||||
{base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN, base::MayBlock()},
|
||||
base::BindOnce(&SetUpCoreMLCacheDir));
|
||||
#endif
|
||||
const base::CommandLine& browser_command_line =
|
||||
*base::CommandLine::ForCurrentProcess();
|
||||
|
||||
|
@ -22,6 +22,13 @@ component("cpp") {
|
||||
"webnn_trace.h",
|
||||
]
|
||||
|
||||
if (is_mac) {
|
||||
sources += [
|
||||
"coreml_initializer.cc",
|
||||
"coreml_initializer.h",
|
||||
]
|
||||
}
|
||||
|
||||
deps = [
|
||||
"//base",
|
||||
"//mojo/public/cpp/bindings",
|
||||
|
74
services/webnn/public/cpp/coreml_initializer.cc
Normal file
74
services/webnn/public/cpp/coreml_initializer.cc
Normal file
@ -0,0 +1,74 @@
|
||||
// Copyright 2025 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "services/webnn/public/cpp/coreml_initializer.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "base/apple/foundation_util.h"
|
||||
#include "base/base_paths_posix.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/functional/callback.h"
|
||||
#include "base/location.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/no_destructor.h"
|
||||
#include "base/one_shot_event.h"
|
||||
#include "base/path_service.h"
|
||||
#include "base/strings/strcat.h"
|
||||
#include "base/task/thread_pool.h"
|
||||
|
||||
namespace webnn {
|
||||
|
||||
namespace {
|
||||
|
||||
void SetupCacheDir() {
|
||||
base::FilePath cache_dir;
|
||||
if (!base::PathService::Get(base::DIR_CACHE, &cache_dir)) {
|
||||
LOG(ERROR) << "Failed to get cache directory for WebNN, this might "
|
||||
"affect the performance and accuracy for WebNN.";
|
||||
return;
|
||||
}
|
||||
cache_dir =
|
||||
cache_dir.Append(base::StrCat({base::apple::BaseBundleID(), ".helper"}))
|
||||
.Append("com.apple.e5rt.e5bundlecache");
|
||||
if (!base::CreateDirectory(cache_dir)) {
|
||||
LOG(ERROR) << "Failed to setup cache directory for WebNN, this might "
|
||||
"affect the performance and accuracy for WebNN.";
|
||||
}
|
||||
}
|
||||
|
||||
class WebNNCoreMLInitializer {
|
||||
public:
|
||||
WebNNCoreMLInitializer() {
|
||||
base::ThreadPool::PostTaskAndReply(
|
||||
FROM_HERE,
|
||||
{base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN, base::MayBlock()},
|
||||
base::BindOnce(&SetupCacheDir),
|
||||
base::BindOnce(&WebNNCoreMLInitializer::OnCacheDirSetupDone,
|
||||
base::Unretained(this)));
|
||||
}
|
||||
|
||||
~WebNNCoreMLInitializer() = delete;
|
||||
|
||||
void RunAfterInitialize(base::OnceClosure callback) {
|
||||
initialized_.Post(FROM_HERE, std::move(callback));
|
||||
}
|
||||
|
||||
private:
|
||||
void OnCacheDirSetupDone() { initialized_.Signal(); }
|
||||
|
||||
base::OneShotEvent initialized_;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
void InitializeCacheDirAndRun(base::OnceClosure callback) {
|
||||
// We only need to initialize once for the whole browser process, and no
|
||||
// teardown logic is needed, so use a global singleton here.
|
||||
static base::NoDestructor<WebNNCoreMLInitializer> g_webnn_coreml_initializer;
|
||||
g_webnn_coreml_initializer->RunAfterInitialize(std::move(callback));
|
||||
}
|
||||
|
||||
} // namespace webnn
|
22
services/webnn/public/cpp/coreml_initializer.h
Normal file
22
services/webnn/public/cpp/coreml_initializer.h
Normal file
@ -0,0 +1,22 @@
|
||||
// Copyright 2025 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SERVICES_WEBNN_PUBLIC_CPP_COREML_INITIALIZER_H_
|
||||
#define SERVICES_WEBNN_PUBLIC_CPP_COREML_INITIALIZER_H_
|
||||
|
||||
#include "base/component_export.h"
|
||||
#include "base/functional/callback_forward.h"
|
||||
|
||||
namespace webnn {
|
||||
|
||||
// This sets up cache directory that's needed for WebNN. WebNN underlying uses
|
||||
// Apple's Core ML framework that needs access to this directory. By creating
|
||||
// the directory in the browser process, we don't need to give the GPU process
|
||||
// the ability to create directories in the sandbox policy.
|
||||
COMPONENT_EXPORT(WEBNN_PUBLIC_CPP)
|
||||
void InitializeCacheDirAndRun(base::OnceClosure callback);
|
||||
|
||||
} // namespace webnn
|
||||
|
||||
#endif // SERVICES_WEBNN_PUBLIC_CPP_COREML_INITIALIZER_H_
|
Reference in New Issue
Block a user