[ios blink] Use BELayerHierarchy for passing surfaces
The CAContext id way of passing surfaces between the GPU process and browser did not work on device. Move to the actual supported API of binding a BELayerHierarchy and BELayerHierarchyHostingView to simplify the code. One complexity is that the BELayerHierarchy needs to be passed as an xpc_object across the channel. Since this can't go across mojo we have to hook it to pass it across the original xpc_connection that bootstrapped mojo. Bug: 40254930 Change-Id: If551283037519754641e44402e474c4ad9048657 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6254053 Reviewed-by: ccameron chromium <ccameron@chromium.org> Commit-Queue: Dave Tapuska <dtapuska@chromium.org> Cr-Commit-Position: refs/heads/main@{#1419977}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
8adb2dee63
commit
700bf2c06e
content
app
browser
gpu/ipc
common
service
ui
@ -2,3 +2,6 @@ per-file sandbox_helper_win.cc=file://sandbox/win/OWNERS
|
||||
|
||||
# For threading and startup/shutdown sequences (ContentMainRunner, etc.)
|
||||
per-file content_main_runner*=gab@chromium.org
|
||||
|
||||
# Security reviews for xpc IPC
|
||||
per-file ios/appex/child_process_bridge.mm=file://ipc/SECURITY_OWNERS
|
||||
|
@ -22,6 +22,7 @@ source_set("child_process_bridge") {
|
||||
deps = [
|
||||
":child_process_bridge_header",
|
||||
"//base",
|
||||
"//gpu/ipc/common",
|
||||
]
|
||||
frameworks = [ "Foundation.framework" ]
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
void ChildProcessInit(id<ChildProcessExtension> process);
|
||||
void GpuProcessInit();
|
||||
void ChildProcessHandleNewConnection(xpc_connection_t connection);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -15,21 +15,47 @@
|
||||
#include "base/apple/bundle_locations.h"
|
||||
#include "base/apple/mach_port_rendezvous.h"
|
||||
#include "base/check_op.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/system/sys_info.h"
|
||||
#include "content/app/ios/appex/child_process_sandbox.h"
|
||||
#include "gpu/ipc/common/ios/be_layer_hierarchy_transport.h"
|
||||
|
||||
class GPUProcessTransport;
|
||||
|
||||
// Leaked variables for now.
|
||||
static size_t g_argc = 0;
|
||||
static const char** g_argv = nullptr;
|
||||
static pthread_t g_main_thread;
|
||||
static id<ChildProcessExtension> g_swift_process;
|
||||
static xpc_connection_t g_connection;
|
||||
static std::unique_ptr<GPUProcessTransport> g_gpu_transport;
|
||||
|
||||
#define IOS_INIT_EXPORT __attribute__((visibility("default")))
|
||||
|
||||
// The embedder must implement this.
|
||||
extern "C" int ChildProcessMain(int argc, const char** argv);
|
||||
|
||||
class GPUProcessTransport : public gpu::BELayerHierarchyTransport {
|
||||
public:
|
||||
GPUProcessTransport() { gpu::BELayerHierarchyTransport::SetInstance(this); }
|
||||
~GPUProcessTransport() override {
|
||||
gpu::BELayerHierarchyTransport::SetInstance(nullptr);
|
||||
}
|
||||
|
||||
void ForwardBELayerHierarchyToBrowser(
|
||||
gpu::SurfaceHandle surface_handle,
|
||||
xpc_object_t ipc_representation) override {
|
||||
xpc_object_t message = xpc_dictionary_create(nil, nil, 0);
|
||||
xpc_dictionary_set_string(message, "message", "layerHandle");
|
||||
xpc_dictionary_set_value(message, "layer", ipc_representation);
|
||||
xpc_dictionary_set_uint64(message, "handle", surface_handle);
|
||||
xpc_connection_send_message(g_connection, message);
|
||||
}
|
||||
};
|
||||
|
||||
extern "C" IOS_INIT_EXPORT void GpuProcessInit() {
|
||||
g_gpu_transport = std::make_unique<GPUProcessTransport>();
|
||||
}
|
||||
|
||||
extern "C" IOS_INIT_EXPORT void ChildProcessInit(
|
||||
id<ChildProcessExtension> process) {
|
||||
// Up two levels: chrome.app/Extensions/chrome_content_process.appex
|
||||
@ -81,6 +107,7 @@ extern "C" IOS_INIT_EXPORT void ChildProcessHandleNewConnection(
|
||||
pthread_create(&g_main_thread, NULL, RunMain, NULL);
|
||||
});
|
||||
xpc_connection_activate(connection);
|
||||
g_connection = connection;
|
||||
}
|
||||
|
||||
namespace content {
|
||||
|
@ -11,6 +11,7 @@ class GPUProcess: NSObject, ChildProcessExtension, RenderingExtension {
|
||||
override required init() {
|
||||
super.init()
|
||||
ChildProcessInit(self)
|
||||
GpuProcessInit()
|
||||
}
|
||||
|
||||
public func handle(xpcConnection: xpc_connection_t) {
|
||||
|
@ -20,6 +20,7 @@ per-file browser_child_process_host_impl_receiver_bindings.*=set noparent
|
||||
per-file browser_child_process_host_impl_receiver_bindings.*=file://ipc/SECURITY_OWNERS
|
||||
per-file utility_process_host_receiver_bindings.*=set noparent
|
||||
per-file utility_process_host_receiver_bindings.*=file://ipc/SECURITY_OWNERS
|
||||
per-file child_process_launcher_helper_ios.mm=file://ipc/SECURITY_OWNERS
|
||||
|
||||
per-file host_zoom_*=wjmaclean@chromium.org
|
||||
per-file site_per_process_*=kenrb@chromium.org
|
||||
|
@ -15,7 +15,9 @@
|
||||
#include "content/browser/child_process_launcher_helper_posix.h"
|
||||
#include "content/public/browser/child_process_launcher_utils.h"
|
||||
#include "content/public/common/content_switches.h"
|
||||
#include "gpu/ipc/common/surface_handle.h"
|
||||
#include "services/network/public/mojom/network_service.mojom.h"
|
||||
#include "ui/accelerated_widget_mac/ca_layer_frame_sink_provider.h"
|
||||
|
||||
namespace content {
|
||||
namespace internal {
|
||||
@ -280,10 +282,51 @@ void ChildProcessLauncherHelper::OnChildProcessStarted(
|
||||
xpc_connection_t xpc_connection =
|
||||
launch_result->CreateXPCConnection(&error);
|
||||
if (xpc_connection) {
|
||||
scoped_refptr<base::SequencedTaskRunner> client_task_runner =
|
||||
client_task_runner_;
|
||||
bool is_gpu_process = GetProcessType() == switches::kGpuProcess;
|
||||
|
||||
xpc_connection_set_event_handler(xpc_connection, ^(xpc_object_t event) {
|
||||
if (event == XPC_ERROR_CONNECTION_INTERRUPTED) {
|
||||
if (event == XPC_ERROR_CONNECTION_INTERRUPTED ||
|
||||
event == XPC_ERROR_CONNECTION_INVALID) {
|
||||
OnChildProcessTerminatedOnAnyThread(process_id);
|
||||
}
|
||||
|
||||
const char* message_type = xpc_dictionary_get_string(event, "message");
|
||||
if (message_type && strcmp(message_type, "layerHandle") == 0) {
|
||||
// We only expect this message from the GPU process.
|
||||
if (!is_gpu_process) {
|
||||
xpc_connection_cancel(xpc_connection);
|
||||
return;
|
||||
}
|
||||
xpc_object_t ca_layer_handle =
|
||||
xpc_dictionary_get_value(event, "layer");
|
||||
gpu::SurfaceHandle view_handle =
|
||||
xpc_dictionary_get_uint64(event, "handle");
|
||||
|
||||
// Validate arguments.
|
||||
if (!ca_layer_handle || !view_handle) {
|
||||
xpc_connection_cancel(xpc_connection);
|
||||
return;
|
||||
}
|
||||
|
||||
client_task_runner->PostTask(
|
||||
FROM_HERE,
|
||||
base::BindOnce(
|
||||
[](gpu::SurfaceHandle view_handle,
|
||||
xpc_object_t ca_layer_handle) {
|
||||
NSError* error = nullptr;
|
||||
BELayerHierarchyHandle* be_handle = [BELayerHierarchyHandle
|
||||
handleWithXPCRepresentation:ca_layer_handle
|
||||
error:&error];
|
||||
CALayerFrameSinkProvider* sink =
|
||||
[CALayerFrameSinkProvider lookupByHandle:view_handle];
|
||||
if (sink) {
|
||||
sink.handle = be_handle;
|
||||
}
|
||||
},
|
||||
view_handle, ca_layer_handle));
|
||||
}
|
||||
});
|
||||
xpc_connection_resume(xpc_connection);
|
||||
xpc_object_t message = xpc_dictionary_create(nil, nil, 0);
|
||||
|
@ -21,7 +21,6 @@
|
||||
#include "ui/events/gesture_detection/filtered_gesture_provider.h"
|
||||
|
||||
namespace ui {
|
||||
class DisplayCALayerTree;
|
||||
enum class DomCode : uint32_t;
|
||||
} // namespace ui
|
||||
|
||||
@ -263,7 +262,6 @@ class CONTENT_EXPORT RenderWidgetHostViewIOS
|
||||
|
||||
std::unique_ptr<BrowserCompositorIOS> browser_compositor_;
|
||||
std::unique_ptr<UIViewHolder> ui_view_;
|
||||
std::unique_ptr<ui::DisplayCALayerTree> display_tree_;
|
||||
base::WeakPtrFactory<RenderWidgetHostViewIOS> weak_factory_{this};
|
||||
};
|
||||
|
||||
|
@ -92,15 +92,12 @@ RenderWidgetHostViewIOS::RenderWidgetHostViewIOS(RenderWidgetHost* widget)
|
||||
ui_view_->view_ =
|
||||
[[RenderWidgetUIView alloc] initWithWidget:weak_factory_.GetWeakPtr()];
|
||||
|
||||
display_tree_ =
|
||||
std::make_unique<ui::DisplayCALayerTree>([ui_view_->view_ layer]);
|
||||
|
||||
auto* screen = display::Screen::GetScreen();
|
||||
screen_infos_ =
|
||||
screen->GetScreenInfosNearestDisplay(screen->GetPrimaryDisplay().id());
|
||||
|
||||
browser_compositor_ = std::make_unique<BrowserCompositorIOS>(
|
||||
(uint64_t)(__bridge void*)ui_view_->view_, this, host()->is_hidden(),
|
||||
[ui_view_->view_ viewHandle], this, host()->is_hidden(),
|
||||
host()->GetFrameSinkId());
|
||||
|
||||
if (IsTesting()) {
|
||||
@ -407,10 +404,7 @@ void RenderWidgetHostViewIOS::OnSynchronizedDisplayPropertiesChanged(
|
||||
}
|
||||
|
||||
void RenderWidgetHostViewIOS::UpdateCALayerTree(
|
||||
const gfx::CALayerParams& ca_layer_params) {
|
||||
DCHECK(display_tree_);
|
||||
display_tree_->UpdateCALayerTree(ca_layer_params);
|
||||
}
|
||||
const gfx::CALayerParams& ca_layer_params) {}
|
||||
|
||||
void RenderWidgetHostViewIOS::OnOldViewDidNavigatePreCommit() {
|
||||
CHECK(browser_compositor_) << "Shouldn't be called during destruction!";
|
||||
|
@ -158,6 +158,13 @@ source_set("ipc_common_sources") {
|
||||
frameworks = [ "IOSurface.framework" ]
|
||||
}
|
||||
|
||||
if (is_ios) {
|
||||
sources += [
|
||||
"ios/be_layer_hierarchy_transport.cc",
|
||||
"ios/be_layer_hierarchy_transport.h",
|
||||
]
|
||||
}
|
||||
|
||||
if (!is_nacl && !is_minimal_toolchain) {
|
||||
deps += [ "//ui/gfx/ipc/skia" ]
|
||||
}
|
||||
|
29
gpu/ipc/common/ios/be_layer_hierarchy_transport.cc
Normal file
29
gpu/ipc/common/ios/be_layer_hierarchy_transport.cc
Normal file
@ -0,0 +1,29 @@
|
||||
// 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 "gpu/ipc/common/ios/be_layer_hierarchy_transport.h"
|
||||
|
||||
#include "base/check.h"
|
||||
|
||||
namespace gpu {
|
||||
namespace {
|
||||
|
||||
BELayerHierarchyTransport* g_instance = nullptr;
|
||||
|
||||
} // namespace
|
||||
|
||||
// static
|
||||
BELayerHierarchyTransport* BELayerHierarchyTransport::GetInstance() {
|
||||
DCHECK(g_instance);
|
||||
return g_instance;
|
||||
}
|
||||
|
||||
// static
|
||||
void BELayerHierarchyTransport::SetInstance(
|
||||
BELayerHierarchyTransport* instance) {
|
||||
DCHECK(!g_instance || !instance);
|
||||
g_instance = instance;
|
||||
}
|
||||
|
||||
} // namespace gpu
|
35
gpu/ipc/common/ios/be_layer_hierarchy_transport.h
Normal file
35
gpu/ipc/common/ios/be_layer_hierarchy_transport.h
Normal file
@ -0,0 +1,35 @@
|
||||
// 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 GPU_IPC_COMMON_IOS_BE_LAYER_HIERARCHY_TRANSPORT_H_
|
||||
#define GPU_IPC_COMMON_IOS_BE_LAYER_HIERARCHY_TRANSPORT_H_
|
||||
|
||||
#include <xpc/xpc.h>
|
||||
|
||||
#include "gpu/gpu_export.h"
|
||||
#include "gpu/ipc/common/surface_handle.h"
|
||||
|
||||
namespace gpu {
|
||||
|
||||
// Allows the BELayerHierarchy to be transported from the GPU process
|
||||
// to the browser process. Since BELayerHierarchy is only serializable
|
||||
// over XPC (and not mojo) it needs a hook into the XPC IPC channel.
|
||||
class GPU_EXPORT BELayerHierarchyTransport {
|
||||
public:
|
||||
static BELayerHierarchyTransport* GetInstance();
|
||||
static void SetInstance(BELayerHierarchyTransport* instance);
|
||||
|
||||
// Sends the BELayerHierarchy represented as an xpc_object_t that
|
||||
// is associated with `surface_handle` to the browser process.
|
||||
virtual void ForwardBELayerHierarchyToBrowser(
|
||||
SurfaceHandle surface_handle,
|
||||
xpc_object_t ipc_representation) = 0;
|
||||
|
||||
protected:
|
||||
virtual ~BELayerHierarchyTransport() {}
|
||||
};
|
||||
|
||||
} // namespace gpu
|
||||
|
||||
#endif // GPU_IPC_COMMON_IOS_BE_LAYER_HIERARCHY_TRANSPORT_H_
|
@ -22,7 +22,7 @@ scoped_refptr<gl::Presenter> ImageTransportSurface::CreatePresenter(
|
||||
if (gl::GetGLImplementation() == gl::kGLImplementationEGLGLES2 ||
|
||||
gl::GetGLImplementation() == gl::kGLImplementationEGLANGLE) {
|
||||
return base::MakeRefCounted<ImageTransportSurfaceOverlayMacEGL>(
|
||||
dawn_context_provider);
|
||||
surface_handle, dawn_context_provider);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
@ -22,7 +22,7 @@ scoped_refptr<gl::Presenter> ImageTransportSurface::CreatePresenter(
|
||||
if (gl::GetGLImplementation() == gl::kGLImplementationEGLGLES2 ||
|
||||
gl::GetGLImplementation() == gl::kGLImplementationEGLANGLE) {
|
||||
return base::MakeRefCounted<ImageTransportSurfaceOverlayMacEGL>(
|
||||
dawn_context_provider);
|
||||
surface_handle, dawn_context_provider);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
@ -23,6 +23,10 @@
|
||||
#include "ui/display/types/display_constants.h"
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(IS_IOS)
|
||||
#include <BrowserEngineKit/BrowserEngineKit.h>
|
||||
#endif
|
||||
|
||||
@class CAContext;
|
||||
@class CALayer;
|
||||
|
||||
@ -36,6 +40,7 @@ namespace gpu {
|
||||
class ImageTransportSurfaceOverlayMacEGL : public gl::Presenter {
|
||||
public:
|
||||
ImageTransportSurfaceOverlayMacEGL(
|
||||
SurfaceHandle surface_handle,
|
||||
DawnContextProvider* dawn_context_provider);
|
||||
|
||||
// Presenter implementation
|
||||
@ -105,6 +110,10 @@ class ImageTransportSurfaceOverlayMacEGL : public gl::Presenter {
|
||||
base::TimeDelta frame_interval_;
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(IS_IOS)
|
||||
BELayerHierarchy* __strong layer_hierarchy_;
|
||||
#endif
|
||||
|
||||
int cap_max_pending_swaps_ = 1;
|
||||
|
||||
raw_ptr<DawnContextProvider> dawn_context_provider_ = nullptr;
|
||||
|
@ -27,6 +27,10 @@
|
||||
#include "ui/gfx/overlay_plane_data.h"
|
||||
#include "ui/gl/ca_renderer_layer_params.h"
|
||||
|
||||
#if BUILDFLAG(IS_IOS)
|
||||
#include "gpu/ipc/common/ios/be_layer_hierarchy_transport.h"
|
||||
#endif
|
||||
|
||||
// From ANGLE's EGL/eglext_angle.h. This should be included instead of being
|
||||
// redefined here.
|
||||
#ifndef EGL_ANGLE_device_metal
|
||||
@ -64,6 +68,7 @@ void RecordVSyncCallbackDelay(base::TimeDelta delay) {
|
||||
} // namespace
|
||||
|
||||
ImageTransportSurfaceOverlayMacEGL::ImageTransportSurfaceOverlayMacEGL(
|
||||
SurfaceHandle surface_handle,
|
||||
DawnContextProvider* dawn_context_provider)
|
||||
: dawn_context_provider_(dawn_context_provider), weak_ptr_factory_(this) {
|
||||
static bool av_disabled_at_command_line =
|
||||
@ -75,10 +80,36 @@ ImageTransportSurfaceOverlayMacEGL::ImageTransportSurfaceOverlayMacEGL(
|
||||
|
||||
ca_layer_tree_coordinator_ = std::make_unique<ui::CALayerTreeCoordinator>(
|
||||
!av_disabled_at_command_line, std::move(buffer_presented_callback));
|
||||
|
||||
#if BUILDFLAG(IS_IOS)
|
||||
// The BELayerHierarchy needs to be created on a thread that supports
|
||||
// libdispatch, so we proxy over to the main dispatch queue to do that.
|
||||
CALayer* root_ca_layer = ca_layer_tree_coordinator_->root_ca_layer();
|
||||
__block xpc_object_t ipc_representation;
|
||||
dispatch_sync(dispatch_get_main_queue(), ^{
|
||||
NSError* error = nullptr;
|
||||
layer_hierarchy_ = [BELayerHierarchy layerHierarchyWithError:&error];
|
||||
layer_hierarchy_.layer = root_ca_layer;
|
||||
ipc_representation = [layer_hierarchy_.handle createXPCRepresentation];
|
||||
});
|
||||
|
||||
BELayerHierarchyTransport* transport =
|
||||
BELayerHierarchyTransport::GetInstance();
|
||||
CHECK(transport);
|
||||
transport->ForwardBELayerHierarchyToBrowser(surface_handle,
|
||||
ipc_representation);
|
||||
#endif
|
||||
}
|
||||
|
||||
ImageTransportSurfaceOverlayMacEGL::~ImageTransportSurfaceOverlayMacEGL() {
|
||||
ca_layer_tree_coordinator_.reset();
|
||||
|
||||
#if BUILDFLAG(IS_IOS)
|
||||
BELayerHierarchy* layer_hierarchy = std::move(layer_hierarchy_);
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[layer_hierarchy invalidate];
|
||||
});
|
||||
#endif
|
||||
}
|
||||
|
||||
void ImageTransportSurfaceOverlayMacEGL::BufferPresented(
|
||||
|
@ -13,8 +13,6 @@ component("accelerated_widget_mac") {
|
||||
"ca_layer_tree_coordinator.mm",
|
||||
"ca_renderer_layer_tree.h",
|
||||
"ca_renderer_layer_tree.mm",
|
||||
"display_ca_layer_tree.h",
|
||||
"display_ca_layer_tree.mm",
|
||||
]
|
||||
|
||||
defines = [
|
||||
@ -47,6 +45,8 @@ component("accelerated_widget_mac") {
|
||||
"accelerated_widget_mac_export.h",
|
||||
"ca_transaction_observer.h",
|
||||
"ca_transaction_observer.mm",
|
||||
"display_ca_layer_tree.h",
|
||||
"display_ca_layer_tree.mm",
|
||||
"io_surface_context.h",
|
||||
"io_surface_context.mm",
|
||||
"window_resize_helper_mac.cc",
|
||||
|
@ -5,6 +5,7 @@
|
||||
#ifndef UI_ACCELERATED_WIDGET_MAC_CA_LAYER_FRAME_SINK_H_
|
||||
#define UI_ACCELERATED_WIDGET_MAC_CA_LAYER_FRAME_SINK_H_
|
||||
|
||||
#include "build/build_config.h"
|
||||
#include "ui/accelerated_widget_mac/accelerated_widget_mac_export.h"
|
||||
#include "ui/gfx/ca_layer_params.h"
|
||||
#include "ui/gfx/native_widget_types.h"
|
||||
|
@ -21,9 +21,8 @@ CALayerFrameSink* CALayerFrameSink::FromAcceleratedWidget(
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
return AcceleratedWidgetMac::Get(widget);
|
||||
#else
|
||||
id object = (__bridge id)(void*)widget;
|
||||
if ([object isKindOfClass:[CALayerFrameSinkProvider class]]) {
|
||||
return [(CALayerFrameSinkProvider*)object frameSink];
|
||||
if (auto* provider = [CALayerFrameSinkProvider lookupByHandle:widget]) {
|
||||
return [provider frameSink];
|
||||
}
|
||||
return nullptr;
|
||||
#endif
|
||||
|
@ -5,6 +5,7 @@
|
||||
#ifndef UI_ACCELERATED_WIDGET_MAC_CA_LAYER_FRAME_SINK_PROVIDER_H_
|
||||
#define UI_ACCELERATED_WIDGET_MAC_CA_LAYER_FRAME_SINK_PROVIDER_H_
|
||||
|
||||
#include <BrowserEngineKit/BrowserEngineKit.h>
|
||||
#include <UIKit/UIKit.h>
|
||||
|
||||
#include "ui/accelerated_widget_mac/accelerated_widget_mac_export.h"
|
||||
@ -15,9 +16,11 @@ namespace ui {
|
||||
class CALayerFrameSink;
|
||||
}
|
||||
|
||||
@interface CALayerFrameSinkProvider : UIView
|
||||
@interface CALayerFrameSinkProvider : BELayerHierarchyHostingView
|
||||
- (id)init;
|
||||
- (ui::CALayerFrameSink*)frameSink;
|
||||
|
||||
- (gfx::AcceleratedWidget)viewHandle;
|
||||
+ (CALayerFrameSinkProvider*)lookupByHandle:(uint64_t)viewHandle;
|
||||
@end
|
||||
|
||||
#endif // UI_ACCELERATED_WIDGET_MAC_CA_LAYER_FRAME_SINK_PROVIDER_H_
|
||||
|
@ -4,8 +4,49 @@
|
||||
|
||||
#import "ui/accelerated_widget_mac/ca_layer_frame_sink_provider.h"
|
||||
|
||||
@implementation CALayerFrameSinkProvider
|
||||
#include <map>
|
||||
|
||||
namespace {
|
||||
|
||||
std::map<gfx::AcceleratedWidget, CALayerFrameSinkProvider*>&
|
||||
WidgetToSinkProviderMap() {
|
||||
static std::map<gfx::AcceleratedWidget, CALayerFrameSinkProvider*> map;
|
||||
return map;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
@implementation CALayerFrameSinkProvider {
|
||||
uint64_t _view_handle;
|
||||
}
|
||||
|
||||
- (ui::CALayerFrameSink*)frameSink {
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (gfx::AcceleratedWidget)viewHandle {
|
||||
return _view_handle;
|
||||
}
|
||||
|
||||
- (id)init {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
static uint64_t last_sequence_number = 0;
|
||||
_view_handle = ++last_sequence_number;
|
||||
WidgetToSinkProviderMap().insert(std::make_pair(_view_handle, self));
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
WidgetToSinkProviderMap().erase(_view_handle);
|
||||
}
|
||||
|
||||
+ (CALayerFrameSinkProvider*)lookupByHandle:(uint64_t)viewHandle {
|
||||
auto found = WidgetToSinkProviderMap().find(viewHandle);
|
||||
if (found == WidgetToSinkProviderMap().end()) {
|
||||
return nullptr;
|
||||
}
|
||||
return found->second;
|
||||
}
|
||||
@end
|
||||
|
@ -95,6 +95,8 @@ class ACCELERATED_WIDGET_MAC_EXPORT CALayerTreeCoordinator {
|
||||
|
||||
int NumPendingSwaps();
|
||||
|
||||
CALayer* root_ca_layer() { return root_ca_layer_; }
|
||||
|
||||
private:
|
||||
uint64_t CreateBackpressureFence();
|
||||
|
||||
|
@ -236,7 +236,7 @@ using NativeViewId = intptr_t;
|
||||
using AcceleratedWidget = HWND;
|
||||
constexpr AcceleratedWidget kNullAcceleratedWidget = nullptr;
|
||||
#elif BUILDFLAG(IS_IOS)
|
||||
using AcceleratedWidget = uint64_t; // A UIView*.
|
||||
using AcceleratedWidget = uint64_t;
|
||||
constexpr AcceleratedWidget kNullAcceleratedWidget = 0;
|
||||
#elif BUILDFLAG(IS_MAC)
|
||||
using AcceleratedWidget = uint64_t;
|
||||
|
Reference in New Issue
Block a user