Commit 51a3f4b6 authored by Christopher Cameron's avatar Christopher Cameron Committed by Commit Bot

Add metal_util component

As part of the investigation of the hangs in the Metal shader compiler,
we will be running some Metal code in the browser process. Create a
stand-alone component for Metal utility functions that will be used
in the browser process and also in the gpu process.

For the moment this functionality includes the C++ Metal types and
the function to select the default Metal device (low-power if
available). Functionality to compile a test shader to determine if
it hangs will also be moved there (and called from the browser
process).

Bug: 974219
Change-Id: Ic6a696686e0c438ec339c6cc40b8200be6b0a689
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1869127
Commit-Queue: ccameron <ccameron@chromium.org>
Reviewed-by: default avatarEric Karl <ericrk@chromium.org>
Reviewed-by: default avatarCait Phillips <caitkp@chromium.org>
Cr-Commit-Position: refs/heads/master@{#708798}
parent 8d172320
# Copyright 2017 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.
import("//testing/test.gni")
component("metal_util") {
output_name = "metal"
defines = [ "METAL_UTIL_IMPLEMENTATION" ]
sources = [
"device.h",
"device.mm",
"metal_util_export.h",
"types.h",
]
deps = [
"//base",
]
libs = [ "Metal.framework" ]
}
include_rules = [
]
ccameron@chromium.org
jvanverth@google.org
# TEAM: graphics-dev@chromium.org
# COMPONENT: Internals>Compositing
# //components/metal_util
metal_util is a set of utility functions for the macOS Metal graphics library.
This is to be a largely stand-alone library with minimal dependencies.
// 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 COMPONENTS_METAL_UTIL_DEVICE_H_
#define COMPONENTS_METAL_UTIL_DEVICE_H_
#include "components/metal_util/metal_util_export.h"
#include "components/metal_util/types.h"
namespace metal {
// Return a low-power device, if one exists, otherwise return the system default
// device.
MTLDevicePtr METAL_UTIL_EXPORT CreateDefaultDevice();
} // namespace metal
#endif // COMPONENTS_METAL_UTIL_DEVICE_H_
// 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 "components/metal_util/device.h"
#import <Metal/Metal.h>
#include "base/mac/scoped_nsobject.h"
namespace metal {
MTLDevicePtr CreateDefaultDevice() {
if (@available(macOS 10.11, *)) {
// First attempt to find a low power device to use.
base::scoped_nsprotocol<id<MTLDevice>> device_to_use;
base::scoped_nsobject<NSArray<id<MTLDevice>>> devices(MTLCopyAllDevices());
for (id<MTLDevice> device in devices.get()) {
if ([device isLowPower]) {
device_to_use.reset(device, base::scoped_policy::RETAIN);
break;
}
}
// Failing that, use the system default device.
if (!device_to_use)
device_to_use.reset(MTLCreateSystemDefaultDevice());
if (!device_to_use) {
DLOG(ERROR) << "Failed to find MTLDevice.";
return nullptr;
}
return device_to_use.release();
}
// If no device was found, or if the macOS version is too old for Metal,
// return no context provider.
return nullptr;
}
} // namespace metal
// 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 COMPONENTS_METAL_UTIL_METAL_UTIL_EXPORT_H_
#define COMPONENTS_METAL_UTIL_METAL_UTIL_EXPORT_H_
#if defined(COMPONENT_BUILD)
#if defined(WIN32)
#if defined(METAL_UTIL_IMPLEMENTATION)
#define METAL_UTIL_EXPORT __declspec(dllexport)
#else
#define METAL_UTIL_EXPORT __declspec(dllimport)
#endif // defined(METAL_UTIL_IMPLEMENTATION)
#else // defined(WIN32)
#if defined(METAL_UTIL_IMPLEMENTATION)
#define METAL_UTIL_EXPORT __attribute__((visibility("default")))
#else
#define METAL_UTIL_EXPORT
#endif
#endif
#else // defined(COMPONENT_BUILD)
#define METAL_UTIL_EXPORT
#endif
#endif // COMPONENTS_METAL_UTIL_METAL_UTIL_EXPORT_H_
// 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 COMPONENTS_METAL_UTIL_TYPES_H_
#define COMPONENTS_METAL_UTIL_TYPES_H_
#if __OBJC__
@protocol MTLDevice;
#endif
namespace metal {
// Metal's API uses Objective-C types, which cannot be included in C++ sources.
// This file defines types that resolve to Metal types in Objective-C sources
// and can be included in C++ sources.
#if __OBJC__
using MTLDevicePtr = id<MTLDevice>;
#else
class MTLDeviceProtocol;
using MTLDevicePtr = MTLDeviceProtocol*;
#endif
} // namespace metal
#endif // COMPONENTS_METAL_UTIL_TYPES_H_
......@@ -61,6 +61,7 @@ if (is_mac) {
deps = [
"//base",
"//components/crash/core/common:crash_key",
"//components/metal_util",
"//ui/gfx",
"//ui/gl",
]
......
......@@ -3,6 +3,7 @@
include_rules = [
"+cc/output",
"+cc/resources",
"+components/metal_util",
"+gpu/command_buffer",
"+gpu/GLES2/gl2extchromium.h",
"+gpu/vulkan",
......
......@@ -6,18 +6,11 @@
#define COMPONENTS_VIZ_COMMON_GPU_METAL_CONTEXT_PROVIDER_H_
#include <memory>
#include "components/metal_util/types.h"
#include "components/viz/common/viz_metal_context_provider_export.h"
class GrContext;
#if __OBJC__
@protocol MTLDevice;
using MTLDevicePtr = id<MTLDevice>;
#else
class MTLDeviceProtocol;
using MTLDevicePtr = MTLDeviceProtocol*;
#endif
namespace gl {
class ProgressReporter;
} // namespace gl
......@@ -33,7 +26,7 @@ class VIZ_METAL_CONTEXT_PROVIDER_EXPORT MetalContextProvider {
virtual ~MetalContextProvider() {}
virtual GrContext* GetGrContext() = 0;
virtual MTLDevicePtr GetMTLDevice() = 0;
virtual metal::MTLDevicePtr GetMTLDevice() = 0;
// Set the progress reported used to prevent watchdog timeouts during longer
// sequences of Metal API calls. It is guaranteed that no further calls to
......
......@@ -9,6 +9,7 @@
#include "base/metrics/histogram_macros.h"
#include "base/synchronization/waitable_event.h"
#include "base/time/time.h"
#include "components/metal_util/device.h"
#include "components/viz/common/gpu/metal_api_proxy.h"
#include "third_party/skia/include/gpu/GrContext.h"
......@@ -100,7 +101,7 @@ struct API_AVAILABLE(macos(10.11)) MetalContextProviderImpl
[device_ setProgressReporter:progress_reporter];
}
GrContext* GetGrContext() override { return gr_context_.get(); }
MTLDevicePtr GetMTLDevice() override { return device_.get(); }
metal::MTLDevicePtr GetMTLDevice() override { return device_.get(); }
private:
base::scoped_nsobject<MTLDeviceProxy> device_;
......@@ -116,17 +117,8 @@ struct API_AVAILABLE(macos(10.11)) MetalContextProviderImpl
std::unique_ptr<MetalContextProvider> MetalContextProvider::Create() {
if (@available(macOS 10.11, *)) {
// First attempt to find a low power device to use.
base::scoped_nsprotocol<id<MTLDevice>> device_to_use;
base::scoped_nsobject<NSArray<id<MTLDevice>>> devices(MTLCopyAllDevices());
for (id<MTLDevice> device in devices.get()) {
if ([device isLowPower]) {
device_to_use.reset(device, base::scoped_policy::RETAIN);
break;
}
}
// Failing that, use the system default device.
if (!device_to_use)
device_to_use.reset(MTLCreateSystemDefaultDevice());
base::scoped_nsprotocol<id<MTLDevice>> device_to_use(
metal::CreateDefaultDevice());
if (!device_to_use) {
DLOG(ERROR) << "Failed to find MTLDevice.";
return nullptr;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment