Commit de566f6b authored by Pawel Osciak's avatar Pawel Osciak Committed by Commit Bot

Add support for protected gpu memory buffers and a secure mode to ArcVDA.

A protected gpu memory buffer is a buffer that can be referred to
by a GpuMemoryBufferHandle, which does not provide access to the buffer's
contents. Such handle can be shared with and received from clients that
should not have access to the buffer's contents. When such handle is
passed to the ProtectedGpuMemoryBufferManager service by its privileged
client, it can be translated into another GpuMemoryBufferHandle, which
allows access to the buffer.

Also, implement a ProtectedMemoryManager to provide an allocation and
lookup service for such buffers for gbm.

Finally, add secure mode API to the ArcVideoAccelerator stack and integrate
it with the above, to provide a secure codec mode implementation.

TEST=E2E video playback tests
BUG=b:27174405,b:62575861,b:27204780

Cq-Include-Trybots: master.tryserver.chromium.android:android_optional_gpu_tests_rel;master.tryserver.chromium.linux:linux_optional_gpu_tests_rel;master.tryserver.chromium.mac:mac_optional_gpu_tests_rel;master.tryserver.chromium.win:win_optional_gpu_tests_rel
Change-Id: I80259db35463f7ed0cc3acc28bf767e55e46c8b8
Reviewed-on: https://chromium-review.googlesource.com/689818Reviewed-by: default avatarKuang-che Wu <kcwu@chromium.org>
Reviewed-by: default avatarOwen Lin <owenlin@chromium.org>
Reviewed-by: default avatarHidehiko Abe <hidehiko@chromium.org>
Reviewed-by: default avatarScott Violet <sky@chromium.org>
Reviewed-by: default avatarRobert Kroeger <rjkroege@chromium.org>
Reviewed-by: default avatarDavid Reveman <reveman@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Reviewed-by: default avatarAntoine Labour <piman@chromium.org>
Reviewed-by: default avatarJorge Lucangeli Obes <jorgelo@chromium.org>
Commit-Queue: Pawel Osciak <posciak@chromium.org>
Cr-Commit-Position: refs/heads/master@{#512797}
parent 0152131a
...@@ -4,12 +4,12 @@ ...@@ -4,12 +4,12 @@
"service_manager:connector": { "service_manager:connector": {
"provides": { "provides": {
"browser": [ "browser": [
"arc::mojom::ProtectedBufferManager",
"arc::mojom::VideoDecodeAccelerator", "arc::mojom::VideoDecodeAccelerator",
"arc::mojom::VideoDecodeClient", "arc::mojom::VideoDecodeClient",
"arc::mojom::VideoEncodeAccelerator", "arc::mojom::VideoEncodeAccelerator",
"arc::mojom::VideoEncodeClient", "arc::mojom::VideoEncodeClient",
"chrome::mojom::ResourceUsageReporter", "chrome::mojom::ResourceUsageReporter",
"media::mojom::ProtectedBufferManager",
"profiling::mojom::ProfilingClient" "profiling::mojom::ProfilingClient"
] ]
} }
......
...@@ -149,7 +149,7 @@ void ArcOemCryptoBridge::ConnectToDaemon( ...@@ -149,7 +149,7 @@ void ArcOemCryptoBridge::ConnectToDaemon(
mojom::OemCryptoServiceRequest request) { mojom::OemCryptoServiceRequest request) {
// Get the Mojo interface from the GPU for dealing with secure buffers and // Get the Mojo interface from the GPU for dealing with secure buffers and
// pass that to the daemon as well in our Connect call. // pass that to the daemon as well in our Connect call.
media::mojom::ProtectedBufferManagerPtr gpu_buffer_manager; mojom::ProtectedBufferManagerPtr gpu_buffer_manager;
content::BindInterfaceInGpuProcess(mojo::MakeRequest(&gpu_buffer_manager)); content::BindInterfaceInGpuProcess(mojo::MakeRequest(&gpu_buffer_manager));
oemcrypto_host_daemon_ptr_->Connect(std::move(request), oemcrypto_host_daemon_ptr_->Connect(std::move(request),
std::move(gpu_buffer_manager)); std::move(gpu_buffer_manager));
......
...@@ -27,6 +27,10 @@ static_library("gpu") { ...@@ -27,6 +27,10 @@ static_library("gpu") {
"gpu_arc_video_decode_accelerator.h", "gpu_arc_video_decode_accelerator.h",
"gpu_arc_video_encode_accelerator.cc", "gpu_arc_video_encode_accelerator.cc",
"gpu_arc_video_encode_accelerator.h", "gpu_arc_video_encode_accelerator.h",
"protected_buffer_manager.cc",
"protected_buffer_manager.h",
"protected_buffer_manager_proxy.cc",
"protected_buffer_manager_proxy.h",
] ]
} }
} }
...@@ -72,6 +72,8 @@ class ArcVideoDecodeAccelerator { ...@@ -72,6 +72,8 @@ class ArcVideoDecodeAccelerator {
struct Config { struct Config {
size_t num_input_buffers = 0; size_t num_input_buffers = 0;
uint32_t input_pixel_format = 0; uint32_t input_pixel_format = 0;
// If true, only buffers created via AllocateProtectedBuffer() may be used.
bool secure_mode = false;
// TODO(owenlin): Add output_pixel_format. For now only the native pixel // TODO(owenlin): Add output_pixel_format. For now only the native pixel
// format of each VDA on Chromium is supported. // format of each VDA on Chromium is supported.
}; };
...@@ -111,10 +113,27 @@ class ArcVideoDecodeAccelerator { ...@@ -111,10 +113,27 @@ class ArcVideoDecodeAccelerator {
// returns SUCCESS iff initialization is successful. // returns SUCCESS iff initialization is successful.
virtual Result Initialize(const Config& config, Client* client) = 0; virtual Result Initialize(const Config& config, Client* client) = 0;
// Allocates a new protected buffer on accelerator side for the given |port|
// and |index|, the contents of which will be inaccessible to the client.
// The protected buffer will remain valid for at least as long as the resource
// backing the passed |handle_fd| is not released (i.e. there is at least one
// reference on the file backing |handle_fd|.
//
// Usable only if the accelerator has been initialized to run in secure mode.
// Allocation for input will create a protected buffer of at least |size|;
// for output, |size| is ignored, and the currently configured output format
// is used instead to determine the required buffer size and format.
virtual bool AllocateProtectedBuffer(PortType port,
uint32_t index,
base::ScopedFD handle_fd,
size_t size) = 0;
// Assigns a shared memory to be used for the accelerator at the specified // Assigns a shared memory to be used for the accelerator at the specified
// port and index. A buffer must be successfully bound before it can be passed // port and index. A buffer must be successfully bound before it can be passed
// to the accelerator via UseBuffer(). Already bound buffers may be reused // to the accelerator via UseBuffer(). Already bound buffers may be reused
// multiple times without additional bindings. // multiple times without additional bindings.
// Not allowed in secure_mode, where protected buffers have to be allocated
// instead.
virtual void BindSharedMemory(PortType port, virtual void BindSharedMemory(PortType port,
uint32_t index, uint32_t index,
base::ScopedFD ashmem_fd, base::ScopedFD ashmem_fd,
...@@ -125,6 +144,8 @@ class ArcVideoDecodeAccelerator { ...@@ -125,6 +144,8 @@ class ArcVideoDecodeAccelerator {
// port and index. A buffer must be successfully bound before it can be // port and index. A buffer must be successfully bound before it can be
// passed to the accelerator via UseBuffer(). Already bound buffers may be // passed to the accelerator via UseBuffer(). Already bound buffers may be
// reused multiple times without additional bindings. // reused multiple times without additional bindings.
// Not allowed in secure_mode, where protected buffers have to be allocated
// instead.
virtual void BindDmabuf( virtual void BindDmabuf(
PortType port, PortType port,
uint32_t index, uint32_t index,
...@@ -134,6 +155,8 @@ class ArcVideoDecodeAccelerator { ...@@ -134,6 +155,8 @@ class ArcVideoDecodeAccelerator {
// Passes a buffer to the accelerator. For input buffer, the accelerator // Passes a buffer to the accelerator. For input buffer, the accelerator
// will process it. For output buffer, the accelerator will output content // will process it. For output buffer, the accelerator will output content
// to it. // to it.
// In secure mode, |port| and |index| must correspond to a protected buffer
// allocated using AllocateProtectedBuffer().
virtual void UseBuffer(PortType port, virtual void UseBuffer(PortType port,
uint32_t index, uint32_t index,
const BufferMetadata& metadata) = 0; const BufferMetadata& metadata) = 0;
......
...@@ -19,6 +19,9 @@ ...@@ -19,6 +19,9 @@
namespace chromeos { namespace chromeos {
namespace arc { namespace arc {
class ProtectedBufferManager;
class ProtectedBufferHandle;
// This class is executed in the GPU process. It takes decoding requests from // This class is executed in the GPU process. It takes decoding requests from
// ARC via IPC channels and translates and sends those requests to an // ARC via IPC channels and translates and sends those requests to an
// implementation of media::VideoDecodeAccelerator. It also returns the decoded // implementation of media::VideoDecodeAccelerator. It also returns the decoded
...@@ -28,8 +31,9 @@ class ChromeArcVideoDecodeAccelerator ...@@ -28,8 +31,9 @@ class ChromeArcVideoDecodeAccelerator
public media::VideoDecodeAccelerator::Client, public media::VideoDecodeAccelerator::Client,
public base::SupportsWeakPtr<ChromeArcVideoDecodeAccelerator> { public base::SupportsWeakPtr<ChromeArcVideoDecodeAccelerator> {
public: public:
explicit ChromeArcVideoDecodeAccelerator( ChromeArcVideoDecodeAccelerator(
const gpu::GpuPreferences& gpu_preferences); const gpu::GpuPreferences& gpu_preferences,
ProtectedBufferManager* protected_buffer_manager);
~ChromeArcVideoDecodeAccelerator() override; ~ChromeArcVideoDecodeAccelerator() override;
// Implementation of the ArcVideoDecodeAccelerator interface. // Implementation of the ArcVideoDecodeAccelerator interface.
...@@ -37,6 +41,10 @@ class ChromeArcVideoDecodeAccelerator ...@@ -37,6 +41,10 @@ class ChromeArcVideoDecodeAccelerator
const Config& config, const Config& config,
ArcVideoDecodeAccelerator::Client* client) override; ArcVideoDecodeAccelerator::Client* client) override;
void SetNumberOfOutputBuffers(size_t number) override; void SetNumberOfOutputBuffers(size_t number) override;
bool AllocateProtectedBuffer(PortType port,
uint32_t index,
base::ScopedFD handle_fd,
size_t size) override;
void BindSharedMemory(PortType port, void BindSharedMemory(PortType port,
uint32_t index, uint32_t index,
base::ScopedFD ashmem_fd, base::ScopedFD ashmem_fd,
...@@ -80,28 +88,34 @@ class ChromeArcVideoDecodeAccelerator ...@@ -80,28 +88,34 @@ class ChromeArcVideoDecodeAccelerator
// The information about the shared memory used as an input buffer. // The information about the shared memory used as an input buffer.
struct InputBufferInfo { struct InputBufferInfo {
// The file handle to access the buffer. It is owned by this class and // SharedMemoryHandle for this buffer to be passed to accelerator.
// should be closed after use. // In non-secure mode, received via BindSharedMemory from the client,
base::ScopedFD handle; // in secure mode, a handle for the SharedMemory in protected_shmem.
base::SharedMemoryHandle shm_handle;
// The offset of the payload to the beginning of the shared memory. // Used only in secure mode; handle to the protected buffer backing
off_t offset = 0; // this input buffer.
std::unique_ptr<ProtectedBufferHandle> protected_buffer_handle;
// The size of the payload in bytes. // Offset to the payload from the beginning of the shared memory buffer.
size_t length = 0; off_t offset = 0;
InputBufferInfo(); InputBufferInfo();
InputBufferInfo(InputBufferInfo&& other);
~InputBufferInfo(); ~InputBufferInfo();
}; };
// The information about the dmabuf used as an output buffer. // The information about the native pixmap used as an output buffer.
struct OutputBufferInfo { struct OutputBufferInfo {
base::ScopedFD handle; // GpuMemoryBufferHandle for this buffer to be passed to accelerator.
std::vector<::arc::VideoFramePlane> planes; // In non-secure mode, received via BindDmabuf from the client,
// in secure mode, a handle to the NativePixmap in protected_pixmap.
gfx::GpuMemoryBufferHandle gpu_memory_buffer_handle;
// Used only in secure mode; handle to the protected buffer backing
// this output buffer.
std::unique_ptr<ProtectedBufferHandle> protected_buffer_handle;
OutputBufferInfo(); OutputBufferInfo();
OutputBufferInfo(OutputBufferInfo&& other);
~OutputBufferInfo(); ~OutputBufferInfo();
}; };
...@@ -155,12 +169,12 @@ class ChromeArcVideoDecodeAccelerator ...@@ -155,12 +169,12 @@ class ChromeArcVideoDecodeAccelerator
std::list<InputRecord> input_records_; std::list<InputRecord> input_records_;
// The details of the shared memory of each input buffers. // The details of the shared memory of each input buffers.
std::vector<InputBufferInfo> input_buffer_info_; std::vector<std::unique_ptr<InputBufferInfo>> input_buffer_info_;
// To keep those output buffers which have been bound by bindDmabuf() but // To keep those output buffers which have been bound by bindDmabuf() but
// haven't been passed to VDA yet. Will call VDA::ImportBufferForPicture() // haven't been passed to VDA yet. Will call VDA::ImportBufferForPicture()
// when those buffers are used for the first time. // when those buffers are used for the first time.
std::vector<OutputBufferInfo> buffers_pending_import_; std::vector<std::unique_ptr<OutputBufferInfo>> buffers_pending_import_;
THREAD_CHECKER(thread_checker_); THREAD_CHECKER(thread_checker_);
size_t output_buffer_size_; size_t output_buffer_size_;
...@@ -168,7 +182,10 @@ class ChromeArcVideoDecodeAccelerator ...@@ -168,7 +182,10 @@ class ChromeArcVideoDecodeAccelerator
// The minimal number of requested output buffers. // The minimal number of requested output buffers.
uint32_t requested_num_of_output_buffers_; uint32_t requested_num_of_output_buffers_;
bool secure_mode_ = false;
gpu::GpuPreferences gpu_preferences_; gpu::GpuPreferences gpu_preferences_;
ProtectedBufferManager* protected_buffer_manager_;
DISALLOW_COPY_AND_ASSIGN(ChromeArcVideoDecodeAccelerator); DISALLOW_COPY_AND_ASSIGN(ChromeArcVideoDecodeAccelerator);
}; };
......
...@@ -22,8 +22,14 @@ ...@@ -22,8 +22,14 @@
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
#include "chrome/gpu/gpu_arc_video_decode_accelerator.h" #include "chrome/gpu/gpu_arc_video_decode_accelerator.h"
#include "chrome/gpu/gpu_arc_video_encode_accelerator.h" #include "chrome/gpu/gpu_arc_video_encode_accelerator.h"
#include "chrome/gpu/protected_buffer_manager.h"
#include "chrome/gpu/protected_buffer_manager_proxy.h"
#include "content/public/common/service_manager_connection.h" #include "content/public/common/service_manager_connection.h"
#include "services/service_manager/public/cpp/binder_registry.h" #include "services/service_manager/public/cpp/binder_registry.h"
#if defined(USE_OZONE)
#include "ui/ozone/public/ozone_platform.h"
#include "ui/ozone/public/surface_factory_ozone.h"
#endif
#endif #endif
namespace { namespace {
...@@ -46,6 +52,10 @@ ChromeContentGpuClient::ChromeContentGpuClient() ...@@ -46,6 +52,10 @@ ChromeContentGpuClient::ChromeContentGpuClient()
metrics::CallStackProfileParams::MAY_SHUFFLE))) { metrics::CallStackProfileParams::MAY_SHUFFLE))) {
if (StackSamplingConfiguration::Get()->IsProfilerEnabledForCurrentProcess()) if (StackSamplingConfiguration::Get()->IsProfilerEnabledForCurrentProcess())
stack_sampling_profiler_.Start(); stack_sampling_profiler_.Start();
#if defined(OS_CHROMEOS)
protected_buffer_manager_.reset(new chromeos::arc::ProtectedBufferManager());
#endif
} }
ChromeContentGpuClient::~ChromeContentGpuClient() {} ChromeContentGpuClient::~ChromeContentGpuClient() {}
...@@ -61,6 +71,10 @@ void ChromeContentGpuClient::InitializeRegistry( ...@@ -61,6 +71,10 @@ void ChromeContentGpuClient::InitializeRegistry(
base::Bind(&ChromeContentGpuClient::CreateArcVideoEncodeAccelerator, base::Bind(&ChromeContentGpuClient::CreateArcVideoEncodeAccelerator,
base::Unretained(this)), base::Unretained(this)),
base::ThreadTaskRunnerHandle::Get()); base::ThreadTaskRunnerHandle::Get());
registry->AddInterface(
base::Bind(&ChromeContentGpuClient::CreateProtectedBufferManager,
base::Unretained(this)),
base::ThreadTaskRunnerHandle::Get());
#endif #endif
} }
...@@ -68,6 +82,13 @@ void ChromeContentGpuClient::GpuServiceInitialized( ...@@ -68,6 +82,13 @@ void ChromeContentGpuClient::GpuServiceInitialized(
const gpu::GpuPreferences& gpu_preferences) { const gpu::GpuPreferences& gpu_preferences) {
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
gpu_preferences_ = gpu_preferences; gpu_preferences_ = gpu_preferences;
#if defined(USE_OZONE)
ui::OzonePlatform::GetInstance()
->GetSurfaceFactoryOzone()
->SetGetProtectedNativePixmapDelegate(base::Bind(
&chromeos::arc::ProtectedBufferManager::GetProtectedNativePixmapFor,
base::Unretained(protected_buffer_manager_.get())));
#endif
#endif #endif
metrics::mojom::CallStackProfileCollectorPtr browser_interface; metrics::mojom::CallStackProfileCollectorPtr browser_interface;
...@@ -78,12 +99,11 @@ void ChromeContentGpuClient::GpuServiceInitialized( ...@@ -78,12 +99,11 @@ void ChromeContentGpuClient::GpuServiceInitialized(
} }
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
void ChromeContentGpuClient::CreateArcVideoDecodeAccelerator( void ChromeContentGpuClient::CreateArcVideoDecodeAccelerator(
::arc::mojom::VideoDecodeAcceleratorRequest request) { ::arc::mojom::VideoDecodeAcceleratorRequest request) {
mojo::MakeStrongBinding( mojo::MakeStrongBinding(
base::MakeUnique<chromeos::arc::GpuArcVideoDecodeAccelerator>( base::MakeUnique<chromeos::arc::GpuArcVideoDecodeAccelerator>(
gpu_preferences_), gpu_preferences_, protected_buffer_manager_.get()),
std::move(request)); std::move(request));
} }
...@@ -94,4 +114,12 @@ void ChromeContentGpuClient::CreateArcVideoEncodeAccelerator( ...@@ -94,4 +114,12 @@ void ChromeContentGpuClient::CreateArcVideoEncodeAccelerator(
gpu_preferences_), gpu_preferences_),
std::move(request)); std::move(request));
} }
void ChromeContentGpuClient::CreateProtectedBufferManager(
::arc::mojom::ProtectedBufferManagerRequest request) {
mojo::MakeStrongBinding(
base::MakeUnique<chromeos::arc::GpuArcProtectedBufferManagerProxy>(
protected_buffer_manager_.get()),
std::move(request));
}
#endif #endif
...@@ -12,10 +12,16 @@ ...@@ -12,10 +12,16 @@
#include "content/public/gpu/content_gpu_client.h" #include "content/public/gpu/content_gpu_client.h"
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
#include "components/arc/common/protected_buffer_manager.mojom.h"
#include "components/arc/common/video_decode_accelerator.mojom.h" #include "components/arc/common/video_decode_accelerator.mojom.h"
#include "components/arc/common/video_encode_accelerator.mojom.h" #include "components/arc/common/video_encode_accelerator.mojom.h"
#include "gpu/command_buffer/service/gpu_preferences.h" #include "gpu/command_buffer/service/gpu_preferences.h"
namespace chromeos {
namespace arc {
class ProtectedBufferManager;
} // namespace arc
} // namespace chromeos
#endif #endif
class ChromeContentGpuClient : public content::ContentGpuClient { class ChromeContentGpuClient : public content::ContentGpuClient {
...@@ -35,6 +41,9 @@ class ChromeContentGpuClient : public content::ContentGpuClient { ...@@ -35,6 +41,9 @@ class ChromeContentGpuClient : public content::ContentGpuClient {
void CreateArcVideoEncodeAccelerator( void CreateArcVideoEncodeAccelerator(
::arc::mojom::VideoEncodeAcceleratorRequest request); ::arc::mojom::VideoEncodeAcceleratorRequest request);
void CreateProtectedBufferManager(
::arc::mojom::ProtectedBufferManagerRequest request);
#endif #endif
// Used to profile process startup. // Used to profile process startup.
...@@ -42,6 +51,8 @@ class ChromeContentGpuClient : public content::ContentGpuClient { ...@@ -42,6 +51,8 @@ class ChromeContentGpuClient : public content::ContentGpuClient {
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
gpu::GpuPreferences gpu_preferences_; gpu::GpuPreferences gpu_preferences_;
std::unique_ptr<chromeos::arc::ProtectedBufferManager>
protected_buffer_manager_;
#endif #endif
DISALLOW_COPY_AND_ASSIGN(ChromeContentGpuClient); DISALLOW_COPY_AND_ASSIGN(ChromeContentGpuClient);
......
...@@ -98,6 +98,7 @@ struct TypeConverter<chromeos::arc::ArcVideoDecodeAccelerator::Config, ...@@ -98,6 +98,7 @@ struct TypeConverter<chromeos::arc::ArcVideoDecodeAccelerator::Config,
chromeos::arc::ArcVideoDecodeAccelerator::Config result; chromeos::arc::ArcVideoDecodeAccelerator::Config result;
result.num_input_buffers = input->num_input_buffers; result.num_input_buffers = input->num_input_buffers;
result.input_pixel_format = input->input_pixel_format; result.input_pixel_format = input->input_pixel_format;
result.secure_mode = input->secure_mode;
return result; return result;
} }
}; };
...@@ -108,9 +109,12 @@ namespace chromeos { ...@@ -108,9 +109,12 @@ namespace chromeos {
namespace arc { namespace arc {
GpuArcVideoDecodeAccelerator::GpuArcVideoDecodeAccelerator( GpuArcVideoDecodeAccelerator::GpuArcVideoDecodeAccelerator(
const gpu::GpuPreferences& gpu_preferences) const gpu::GpuPreferences& gpu_preferences,
ProtectedBufferManager* protected_buffer_manager)
: gpu_preferences_(gpu_preferences), : gpu_preferences_(gpu_preferences),
accelerator_(new ChromeArcVideoDecodeAccelerator(gpu_preferences_)) {} accelerator_(std::make_unique<ChromeArcVideoDecodeAccelerator>(
gpu_preferences_,
protected_buffer_manager)) {}
GpuArcVideoDecodeAccelerator::~GpuArcVideoDecodeAccelerator() { GpuArcVideoDecodeAccelerator::~GpuArcVideoDecodeAccelerator() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
...@@ -166,7 +170,9 @@ void GpuArcVideoDecodeAccelerator::Initialize( ...@@ -166,7 +170,9 @@ void GpuArcVideoDecodeAccelerator::Initialize(
LOG(ERROR) << "only decoder is supported"; LOG(ERROR) << "only decoder is supported";
std::move(callback).Run( std::move(callback).Run(
::arc::mojom::VideoDecodeAccelerator::Result::INVALID_ARGUMENT); ::arc::mojom::VideoDecodeAccelerator::Result::INVALID_ARGUMENT);
return;
} }
client_ = std::move(client); client_ = std::move(client);
ArcVideoDecodeAccelerator::Result result = accelerator_->Initialize( ArcVideoDecodeAccelerator::Result result = accelerator_->Initialize(
config.To<ArcVideoDecodeAccelerator::Config>(), this); config.To<ArcVideoDecodeAccelerator::Config>(), this);
...@@ -197,6 +203,26 @@ base::ScopedFD GpuArcVideoDecodeAccelerator::UnwrapFdFromMojoHandle( ...@@ -197,6 +203,26 @@ base::ScopedFD GpuArcVideoDecodeAccelerator::UnwrapFdFromMojoHandle(
return base::ScopedFD(platform_file); return base::ScopedFD(platform_file);
} }
void GpuArcVideoDecodeAccelerator::AllocateProtectedBuffer(
::arc::mojom::PortType port,
uint32_t index,
mojo::ScopedHandle handle,
uint64_t size,
AllocateProtectedBufferCallback callback) {
DVLOG(2) << "port=" << port << ", index=" << index << ", size=" << size;
base::ScopedFD fd = UnwrapFdFromMojoHandle(std::move(handle));
if (!fd.is_valid()) {
std::move(callback).Run(false);
return;
}
bool result = accelerator_->AllocateProtectedBuffer(
static_cast<PortType>(port), index, std::move(fd), size);
std::move(callback).Run(result);
}
void GpuArcVideoDecodeAccelerator::BindSharedMemory( void GpuArcVideoDecodeAccelerator::BindSharedMemory(
::arc::mojom::PortType port, ::arc::mojom::PortType port,
uint32_t index, uint32_t index,
......
...@@ -19,6 +19,8 @@ ...@@ -19,6 +19,8 @@
namespace chromeos { namespace chromeos {
namespace arc { namespace arc {
class ProtectedBufferManager;
// GpuArcVideoDecodeAccelerator manages life-cycle and IPC message translation // GpuArcVideoDecodeAccelerator manages life-cycle and IPC message translation
// for ArcVideoDecodeAccelerator. // for ArcVideoDecodeAccelerator.
// //
...@@ -28,8 +30,9 @@ class GpuArcVideoDecodeAccelerator ...@@ -28,8 +30,9 @@ class GpuArcVideoDecodeAccelerator
: public ::arc::mojom::VideoDecodeAccelerator, : public ::arc::mojom::VideoDecodeAccelerator,
public ArcVideoDecodeAccelerator::Client { public ArcVideoDecodeAccelerator::Client {
public: public:
explicit GpuArcVideoDecodeAccelerator( GpuArcVideoDecodeAccelerator(
const gpu::GpuPreferences& gpu_preferences); const gpu::GpuPreferences& gpu_preferences,
ProtectedBufferManager* protected_buffer_manager);
~GpuArcVideoDecodeAccelerator() override; ~GpuArcVideoDecodeAccelerator() override;
private: private:
...@@ -46,6 +49,14 @@ class GpuArcVideoDecodeAccelerator ...@@ -46,6 +49,14 @@ class GpuArcVideoDecodeAccelerator
void Initialize(::arc::mojom::VideoDecodeAcceleratorConfigPtr config, void Initialize(::arc::mojom::VideoDecodeAcceleratorConfigPtr config,
::arc::mojom::VideoDecodeClientPtr client, ::arc::mojom::VideoDecodeClientPtr client,
InitializeCallback callback) override; InitializeCallback callback) override;
void AllocateProtectedBuffer(
::arc::mojom::PortType port,
uint32_t index,
mojo::ScopedHandle handle,
uint64_t size,
AllocateProtectedBufferCallback callback) override;
void BindSharedMemory(::arc::mojom::PortType port, void BindSharedMemory(::arc::mojom::PortType port,
uint32_t index, uint32_t index,
mojo::ScopedHandle ashmem_handle, mojo::ScopedHandle ashmem_handle,
......
This diff is collapsed.
// 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.
#ifndef CHROME_GPU_PROTECTED_BUFFER_MANAGER_H_
#define CHROME_GPU_PROTECTED_BUFFER_MANAGER_H_
#include <map>
#include "base/memory/ref_counted.h"
#include "base/memory/shared_memory.h"
#include "base/memory/weak_ptr.h"
#include "base/synchronization/lock.h"
#include "ui/gfx/gpu_memory_buffer.h"
#include "ui/gfx/native_pixmap.h"
namespace chromeos {
namespace arc {
// A ProtectedBufferHandle is returned to the owning client that requested
// the underlying ProtectedBuffer to be allocated.
//
// A ProtectedBuffer is a buffer that can be referred to via a handle (a dummy
// handle), which does not provide access to the actual contents of the buffer.
//
// The client should release this handle once the buffer is no longer needed.
// Releasing triggers destruction of the ProtectedBuffer instance stored in
// the ProtectedBufferManager, via the destruction callback passed to the
// ProtectedBufferHandle's constructor.
class ProtectedBufferHandle {
public:
// ProtectedBufferHandle takes ownership of the passed |shm_handle|.
ProtectedBufferHandle(base::OnceClosure destruction_cb,
const base::SharedMemoryHandle& shm_handle);
// ProtectedBufferHandle takes ownership of the passed |native_pixmap_handle|.
ProtectedBufferHandle(base::OnceClosure destruction_cb,
const gfx::NativePixmapHandle& native_pixmap_handle);
// Closes the underlying handle.
~ProtectedBufferHandle();
// Return a non-owned SharedMemoryHandle or NativePixmapHandle for this
// ProtectedBufferHandle, or an invalid/null handle if not applicable for the
// underlying type.
base::SharedMemoryHandle shm_handle() const;
gfx::NativePixmapHandle native_pixmap_handle() const;
private:
// The underlying, owning handles to the protected buffer.
// Only one of the handles is valid for each instance of this class.
// Closed on destruction of this ProtectedBufferHandle.
base::SharedMemoryHandle shm_handle_;
gfx::NativePixmapHandle native_pixmap_handle_;
base::OnceClosure destruction_cb_;
};
class ProtectedBufferManager {
public:
ProtectedBufferManager();
~ProtectedBufferManager();
// Allocate a ProtectedSharedMemory buffer of |size| bytes, to be referred to
// via |dummy_fd| as the dummy handle, returning a ProtectedBufferHandle to
// it.
// Destroying the ProtectedBufferHandle will result in permanently
// disassociating the |dummy_fd| with the underlying ProtectedBuffer, but may
// not free the underlying protected memory, which will remain valid as long
// as any SharedMemoryHandles to it are still in use.
// Return nullptr on failure.
std::unique_ptr<ProtectedBufferHandle> AllocateProtectedSharedMemory(
base::ScopedFD dummy_fd,
size_t size);
// Allocate a ProtectedNativePixmap of |format| and |size|, to be referred to
// via |dummy_fd| as the dummy handle, returning a ProtectedBufferHandle to
// it.
// Destroying the ProtectedBufferHandle will result in permanently
// disassociating the |dummy_fd| with the underlying ProtectedBuffer, but may
// not free the underlying protected memory, which will remain valid as long
// as any NativePixmapHandles to it are still in use.
// Return nullptr on failure.
std::unique_ptr<ProtectedBufferHandle> AllocateProtectedNativePixmap(
base::ScopedFD dummy_fd,
gfx::BufferFormat format,
const gfx::Size& size);
// Return a duplicated SharedMemoryHandle associated with the |dummy_fd|,
// if one exists, or an invalid handle otherwise.
// The client is responsible for closing the handle after use.
base::SharedMemoryHandle GetProtectedSharedMemoryHandleFor(
base::ScopedFD dummy_fd);
// Return a duplicated NativePixmapHandle associated with the |dummy_fd|,
// if one exists, or an empty handle otherwise.
// The client is responsible for closing the handle after use.
gfx::NativePixmapHandle GetProtectedNativePixmapHandleFor(
base::ScopedFD dummy_fd);
// Return a protected NativePixmap for a dummy |handle|, if one exists, or
// nullptr otherwise. On success, the |handle| is closed.
scoped_refptr<gfx::NativePixmap> GetProtectedNativePixmapFor(
const gfx::NativePixmapHandle& handle);
private:
// Used internally to maintain the association between the dummy handle and
// the underlying buffer.
class ProtectedBuffer;
class ProtectedSharedMemory;
class ProtectedNativePixmap;
// Imports the |dummy_fd| as a NativePixmap. This returns a unique |id|,
// which is guaranteed to be the same for all future imports of any fd
// referring to the buffer to which |dummy_fd| refers to, regardless of
// whether it is the same fd as the original one, or not, for the lifetime
// of the buffer.
//
// This allows us to have an unambiguous mapping from any fd referring to
// the same memory buffer to the same unique id.
//
// Returns nullptr on failure, in which case the returned id is not valid.
scoped_refptr<gfx::NativePixmap> ImportDummyFd(base::ScopedFD dummy_fd,
uint32_t* id) const;
// Removes an entry for given |id| from buffer_map_, to be called when the
// last reference to the buffer is dropped.
void RemoveEntry(uint32_t id);
// A map of unique ids to the ProtectedBuffers associated with them.
using ProtectedBufferMap =
std::map<uint32_t, std::unique_ptr<ProtectedBuffer>>;
ProtectedBufferMap buffer_map_;
base::Lock buffer_map_lock_;
base::WeakPtr<ProtectedBufferManager> weak_this_;
base::WeakPtrFactory<ProtectedBufferManager> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(ProtectedBufferManager);
};
} // namespace arc
} // namespace chromeos
#endif // CHROME_GPU_PROTECTED_BUFFER_MANAGER_H_
// 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.
#include "chrome/gpu/protected_buffer_manager_proxy.h"
#include "chrome/gpu/protected_buffer_manager.h"
#include "mojo/public/cpp/system/platform_handle.h"
#define VLOGF(level) VLOG(level) << __func__ << "(): "
namespace chromeos {
namespace arc {
GpuArcProtectedBufferManagerProxy::GpuArcProtectedBufferManagerProxy(
chromeos::arc::ProtectedBufferManager* protected_buffer_manager)
: protected_buffer_manager_(protected_buffer_manager) {
DCHECK(protected_buffer_manager_);
}
base::ScopedFD GpuArcProtectedBufferManagerProxy::UnwrapFdFromMojoHandle(
mojo::ScopedHandle handle) {
base::PlatformFile platform_file;
MojoResult mojo_result =
mojo::UnwrapPlatformFile(std::move(handle), &platform_file);
if (mojo_result != MOJO_RESULT_OK) {
VLOGF(1) << "UnwrapPlatformFile failed: " << mojo_result;
return base::ScopedFD();
}
return base::ScopedFD(platform_file);
}
mojo::ScopedHandle GpuArcProtectedBufferManagerProxy::WrapFdInMojoHandle(
base::ScopedFD fd) {
return mojo::WrapPlatformFile(fd.release());
}
void GpuArcProtectedBufferManagerProxy::GetProtectedSharedMemoryFromHandle(
mojo::ScopedHandle dummy_handle,
GetProtectedSharedMemoryFromHandleCallback callback) {
base::ScopedFD unwrapped_fd = UnwrapFdFromMojoHandle(std::move(dummy_handle));
base::ScopedFD shmem_fd(
protected_buffer_manager_
->GetProtectedSharedMemoryHandleFor(std::move(unwrapped_fd))
.Release());
std::move(callback).Run(WrapFdInMojoHandle(std::move(shmem_fd)));
}
} // namespace arc
} // namespace chromeos
// 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.
#ifndef CHROME_GPU_PROTECTED_BUFFER_MANAGER_PROXY_H_
#define CHROME_GPU_PROTECTED_BUFFER_MANAGER_PROXY_H_
#include "components/arc/common/protected_buffer_manager.mojom.h"
namespace chromeos {
namespace arc {
class ProtectedBufferManager;
// Manages mojo IPC translation for chromeos::arc::ProtectedBufferManager.
class GpuArcProtectedBufferManagerProxy
: public ::arc::mojom::ProtectedBufferManager {
public:
explicit GpuArcProtectedBufferManagerProxy(
chromeos::arc::ProtectedBufferManager* protected_buffer_manager);
// arc::mojom::ProtectedBufferManager implementation.
void GetProtectedSharedMemoryFromHandle(
mojo::ScopedHandle dummy_handle,
GetProtectedSharedMemoryFromHandleCallback callback) override;
private:
base::ScopedFD UnwrapFdFromMojoHandle(mojo::ScopedHandle handle);
mojo::ScopedHandle WrapFdInMojoHandle(base::ScopedFD fd);
chromeos::arc::ProtectedBufferManager* protected_buffer_manager_;
DISALLOW_COPY_AND_ASSIGN(GpuArcProtectedBufferManagerProxy);
};
} // namespace arc
} // namespace chromeos
#endif // CHROME_GPU_PROTECTED_BUFFER_MANAGER_PROXY_H_
...@@ -21,5 +21,5 @@ import "protected_buffer_manager.mojom"; ...@@ -21,5 +21,5 @@ import "protected_buffer_manager.mojom";
// Next Method ID: 1 // Next Method ID: 1
interface OemCryptoHostDaemon { interface OemCryptoHostDaemon {
Connect@0(arc.mojom.OemCryptoService& oemcryptor, Connect@0(arc.mojom.OemCryptoService& oemcryptor,
media.mojom.ProtectedBufferManager protected_buffer_manager); arc.mojom.ProtectedBufferManager protected_buffer_manager);
}; };
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
// The original version of this file lives in the Chromium repository at: // The original version of this file lives in the Chromium repository at:
// src/components/arc/common/protected_buffer_manager.mojom // src/components/arc/common/protected_buffer_manager.mojom
module media.mojom; module arc.mojom;
// This interface is exposed by the GPU process for translating dummy handles // This interface is exposed by the GPU process for translating dummy handles
// for secure buffers into a usable shared memory handle. The output of a // for secure buffers into a usable shared memory handle. The output of a
......
...@@ -40,6 +40,7 @@ struct VideoFormat { ...@@ -40,6 +40,7 @@ struct VideoFormat {
uint32 crop_height; uint32 crop_height;
}; };
// Next MinVersion: 2
struct VideoDecodeAcceleratorConfig { struct VideoDecodeAcceleratorConfig {
// Deprecated. This config struct is used for decoder only. // Deprecated. This config struct is used for decoder only.
enum DeviceTypeDeprecated { enum DeviceTypeDeprecated {
...@@ -51,11 +52,12 @@ struct VideoDecodeAcceleratorConfig { ...@@ -51,11 +52,12 @@ struct VideoDecodeAcceleratorConfig {
DeviceTypeDeprecated device_type_deprecated; DeviceTypeDeprecated device_type_deprecated;
uint32 num_input_buffers; uint32 num_input_buffers;
uint32 input_pixel_format; uint32 input_pixel_format;
[MinVersion=1] bool secure_mode;
}; };
// Next MinVersion: 4 // Next MinVersion: 5
// Deprecated method IDs: 2, 7 // Deprecated method IDs: 2, 7
// Next method ID: 10 // Next method ID: 11
interface VideoDecodeAccelerator { interface VideoDecodeAccelerator {
enum Result { enum Result {
SUCCESS = 0, SUCCESS = 0,
...@@ -70,6 +72,10 @@ interface VideoDecodeAccelerator { ...@@ -70,6 +72,10 @@ interface VideoDecodeAccelerator {
Initialize@8(VideoDecodeAcceleratorConfig config, Initialize@8(VideoDecodeAcceleratorConfig config,
VideoDecodeClient client) => (Result result); VideoDecodeClient client) => (Result result);
[MinVersion=4]
AllocateProtectedBuffer@10(PortType port, uint32 index, handle handle_fd,
uint64 size) => (bool result);
BindSharedMemory@1(PortType port, uint32 index, handle ashmem_fd, BindSharedMemory@1(PortType port, uint32 index, handle ashmem_fd,
uint32 offset, uint32 length); uint32 offset, uint32 length);
......
...@@ -132,6 +132,8 @@ component("gpu") { ...@@ -132,6 +132,8 @@ component("gpu") {
"fake_jpeg_decode_accelerator.h", "fake_jpeg_decode_accelerator.h",
"fake_video_decode_accelerator.cc", "fake_video_decode_accelerator.cc",
"fake_video_decode_accelerator.h", "fake_video_decode_accelerator.h",
"format_utils.cc",
"format_utils.h",
"gles2_decoder_helper.cc", "gles2_decoder_helper.cc",
"gles2_decoder_helper.h", "gles2_decoder_helper.h",
"gpu_video_accelerator_util.cc", "gpu_video_accelerator_util.cc",
......
// 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.
#include "media/gpu/format_utils.h"
#include "base/logging.h"
namespace media {
VideoPixelFormat GfxBufferFormatToVideoPixelFormat(gfx::BufferFormat format) {
switch (format) {
case gfx::BufferFormat::BGRX_8888:
return PIXEL_FORMAT_XRGB;
case gfx::BufferFormat::BGRA_8888:
return PIXEL_FORMAT_ARGB;
case gfx::BufferFormat::YVU_420:
return PIXEL_FORMAT_YV12;
case gfx::BufferFormat::YUV_420_BIPLANAR:
return PIXEL_FORMAT_NV12;
default:
LOG(FATAL) << "Add more cases as needed";
return PIXEL_FORMAT_UNKNOWN;
}
}
gfx::BufferFormat VideoPixelFormatToGfxBufferFormat(
VideoPixelFormat pixel_format) {
switch (pixel_format) {
case PIXEL_FORMAT_ARGB:
return gfx::BufferFormat::BGRA_8888;
case PIXEL_FORMAT_XRGB:
return gfx::BufferFormat::BGRX_8888;
case PIXEL_FORMAT_YV12:
return gfx::BufferFormat::YVU_420;
case PIXEL_FORMAT_NV12:
return gfx::BufferFormat::YUV_420_BIPLANAR;
default:
LOG(FATAL) << "Add more cases as needed";
return gfx::BufferFormat::BGRX_8888;
}
}
} // namespace media
// 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.
#ifndef MEDIA_GPU_FORMAT_UTILS_H_
#define MEDIA_GPU_FORMAT_UTILS_H_
#include "media/base/video_types.h"
#include "ui/gfx/buffer_types.h"
namespace media {
VideoPixelFormat GfxBufferFormatToVideoPixelFormat(gfx::BufferFormat format);
gfx::BufferFormat VideoPixelFormatToGfxBufferFormat(
VideoPixelFormat pixel_format);
} // namespace media
#endif // MEDIA_GPU_FORMAT_UTILS_H_
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include "gpu/ipc/service/gpu_channel.h" #include "gpu/ipc/service/gpu_channel.h"
#include "media/base/bind_to_current_loop.h" #include "media/base/bind_to_current_loop.h"
#include "media/gpu/accelerated_video_decoder.h" #include "media/gpu/accelerated_video_decoder.h"
#include "media/gpu/format_utils.h"
#include "media/gpu/h264_decoder.h" #include "media/gpu/h264_decoder.h"
#include "media/gpu/vaapi_picture.h" #include "media/gpu/vaapi_picture.h"
#include "media/gpu/vp8_decoder.h" #include "media/gpu/vp8_decoder.h"
...@@ -706,24 +707,6 @@ void VaapiVideoDecodeAccelerator::InitiateSurfaceSetChange(size_t num_pics, ...@@ -706,24 +707,6 @@ void VaapiVideoDecodeAccelerator::InitiateSurfaceSetChange(size_t num_pics,
TryFinishSurfaceSetChange(); TryFinishSurfaceSetChange();
} }
static VideoPixelFormat BufferFormatToVideoPixelFormat(
gfx::BufferFormat format) {
switch (format) {
case gfx::BufferFormat::BGRX_8888:
return PIXEL_FORMAT_XRGB;
case gfx::BufferFormat::BGRA_8888:
return PIXEL_FORMAT_ARGB;
case gfx::BufferFormat::YVU_420:
return PIXEL_FORMAT_YV12;
default:
LOG(FATAL) << "Add more cases as needed";
return PIXEL_FORMAT_UNKNOWN;
}
}
void VaapiVideoDecodeAccelerator::TryFinishSurfaceSetChange() { void VaapiVideoDecodeAccelerator::TryFinishSurfaceSetChange() {
DCHECK(task_runner_->BelongsToCurrentThread()); DCHECK(task_runner_->BelongsToCurrentThread());
...@@ -763,7 +746,7 @@ void VaapiVideoDecodeAccelerator::TryFinishSurfaceSetChange() { ...@@ -763,7 +746,7 @@ void VaapiVideoDecodeAccelerator::TryFinishSurfaceSetChange() {
VLOGF(2) << "Requesting " << requested_num_pics_ VLOGF(2) << "Requesting " << requested_num_pics_
<< " pictures of size: " << requested_pic_size_.ToString(); << " pictures of size: " << requested_pic_size_.ToString();
VideoPixelFormat format = BufferFormatToVideoPixelFormat(output_format_); VideoPixelFormat format = GfxBufferFormatToVideoPixelFormat(output_format_);
task_runner_->PostTask( task_runner_->PostTask(
FROM_HERE, base::Bind(&Client::ProvidePictureBuffers, client_, FROM_HERE, base::Bind(&Client::ProvidePictureBuffers, client_,
requested_num_pics_, format, 1, requested_pic_size_, requested_num_pics_, format, 1, requested_pic_size_,
......
...@@ -61,6 +61,7 @@ ...@@ -61,6 +61,7 @@
#include "media/base/test_data_util.h" #include "media/base/test_data_util.h"
#include "media/gpu/fake_video_decode_accelerator.h" #include "media/gpu/fake_video_decode_accelerator.h"
#include "media/gpu/features.h" #include "media/gpu/features.h"
#include "media/gpu/format_utils.h"
#include "media/gpu/gpu_video_decode_accelerator_factory.h" #include "media/gpu/gpu_video_decode_accelerator_factory.h"
#include "media/gpu/rendering_helper.h" #include "media/gpu/rendering_helper.h"
#include "media/gpu/video_accelerator_unittest_helpers.h" #include "media/gpu/video_accelerator_unittest_helpers.h"
...@@ -340,23 +341,6 @@ scoped_refptr<TextureRef> TextureRef::Create( ...@@ -340,23 +341,6 @@ scoped_refptr<TextureRef> TextureRef::Create(
return base::WrapRefCounted(new TextureRef(texture_id, no_longer_needed_cb)); return base::WrapRefCounted(new TextureRef(texture_id, no_longer_needed_cb));
} }
#if defined(OS_CHROMEOS)
gfx::BufferFormat VideoPixelFormatToGfxBufferFormat(
VideoPixelFormat pixel_format) {
switch (pixel_format) {
case VideoPixelFormat::PIXEL_FORMAT_ARGB:
return gfx::BufferFormat::BGRA_8888;
case VideoPixelFormat::PIXEL_FORMAT_XRGB:
return gfx::BufferFormat::BGRX_8888;
case VideoPixelFormat::PIXEL_FORMAT_NV12:
return gfx::BufferFormat::YUV_420_BIPLANAR;
default:
LOG_ASSERT(false) << "Unknown VideoPixelFormat";
return gfx::BufferFormat::BGRX_8888;
}
}
#endif
// static // static
scoped_refptr<TextureRef> TextureRef::CreatePreallocated( scoped_refptr<TextureRef> TextureRef::CreatePreallocated(
uint32_t texture_id, uint32_t texture_id,
......
...@@ -34,6 +34,14 @@ class NativePixmap : public base::RefCountedThreadSafe<NativePixmap> { ...@@ -34,6 +34,14 @@ class NativePixmap : public base::RefCountedThreadSafe<NativePixmap> {
virtual gfx::BufferFormat GetBufferFormat() const = 0; virtual gfx::BufferFormat GetBufferFormat() const = 0;
virtual gfx::Size GetBufferSize() const = 0; virtual gfx::Size GetBufferSize() const = 0;
// Return an id that is guaranteed to be unique and equal for all instances
// of this NativePixmap backed by the same buffer, for the duration of its
// lifetime. If such id cannot be generated, 0 (an invalid id) is returned.
//
// TODO(posciak): crbug.com/771863, remove this once a different mechanism
// for protected shared memory buffers is implemented.
virtual uint32_t GetUniqueId() const = 0;
// Sets the overlay plane to switch to at the next page flip. // Sets the overlay plane to switch to at the next page flip.
// |widget| specifies the screen to display this overlay plane on. // |widget| specifies the screen to display this overlay plane on.
// |plane_z_order| specifies the stacking order of the plane relative to the // |plane_z_order| specifies the stacking order of the plane relative to the
......
...@@ -63,6 +63,7 @@ class CastPixmap : public gfx::NativePixmap { ...@@ -63,6 +63,7 @@ class CastPixmap : public gfx::NativePixmap {
return gfx::BufferFormat::BGRA_8888; return gfx::BufferFormat::BGRA_8888;
} }
gfx::Size GetBufferSize() const override { return gfx::Size(); } gfx::Size GetBufferSize() const override { return gfx::Size(); }
uint32_t GetUniqueId() const override { return 0; }
bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget, bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget,
int plane_z_order, int plane_z_order,
......
...@@ -261,11 +261,11 @@ scoped_refptr<GbmBuffer> GbmBuffer::CreateBufferFromFds( ...@@ -261,11 +261,11 @@ scoped_refptr<GbmBuffer> GbmBuffer::CreateBufferFromFds(
// Try to use scanout if supported. // Try to use scanout if supported.
int gbm_flags = GBM_BO_USE_SCANOUT | GBM_BO_USE_TEXTURING; int gbm_flags = GBM_BO_USE_SCANOUT | GBM_BO_USE_TEXTURING;
bool try_scanout = if (!gbm_device_is_format_supported(gbm->device(), format, gbm_flags))
gbm_device_is_format_supported(gbm->device(), format, gbm_flags); gbm_flags &= ~GBM_BO_USE_SCANOUT;
gbm_bo* bo = nullptr; gbm_bo* bo = nullptr;
if (try_scanout) { if (gbm_device_is_format_supported(gbm->device(), format, gbm_flags)) {
struct gbm_import_fd_planar_data fd_data; struct gbm_import_fd_planar_data fd_data;
fd_data.width = size.width(); fd_data.width = size.width();
fd_data.height = size.height(); fd_data.height = size.height();
...@@ -287,8 +287,6 @@ scoped_refptr<GbmBuffer> GbmBuffer::CreateBufferFromFds( ...@@ -287,8 +287,6 @@ scoped_refptr<GbmBuffer> GbmBuffer::CreateBufferFromFds(
LOG(ERROR) << "nullptr returned from gbm_bo_import"; LOG(ERROR) << "nullptr returned from gbm_bo_import";
return nullptr; return nullptr;
} }
} else {
gbm_flags &= ~GBM_BO_USE_SCANOUT;
} }
scoped_refptr<GbmBuffer> buffer(new GbmBuffer(gbm, bo, format, gbm_flags, 0, scoped_refptr<GbmBuffer> buffer(new GbmBuffer(gbm, bo, format, gbm_flags, 0,
...@@ -365,6 +363,10 @@ gfx::Size GbmPixmap::GetBufferSize() const { ...@@ -365,6 +363,10 @@ gfx::Size GbmPixmap::GetBufferSize() const {
return buffer_->GetSize(); return buffer_->GetSize();
} }
uint32_t GbmPixmap::GetUniqueId() const {
return buffer_->GetHandle();
}
bool GbmPixmap::ScheduleOverlayPlane(gfx::AcceleratedWidget widget, bool GbmPixmap::ScheduleOverlayPlane(gfx::AcceleratedWidget widget,
int plane_z_order, int plane_z_order,
gfx::OverlayTransform plane_transform, gfx::OverlayTransform plane_transform,
......
...@@ -119,6 +119,7 @@ class GbmPixmap : public gfx::NativePixmap { ...@@ -119,6 +119,7 @@ class GbmPixmap : public gfx::NativePixmap {
uint64_t GetDmaBufModifier(size_t plane) const override; uint64_t GetDmaBufModifier(size_t plane) const override;
gfx::BufferFormat GetBufferFormat() const override; gfx::BufferFormat GetBufferFormat() const override;
gfx::Size GetBufferSize() const override; gfx::Size GetBufferSize() const override;
uint32_t GetUniqueId() const override;
bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget, bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget,
int plane_z_order, int plane_z_order,
gfx::OverlayTransform plane_transform, gfx::OverlayTransform plane_transform,
......
...@@ -160,7 +160,7 @@ scoped_refptr<gfx::NativePixmap> GbmSurfaceFactory::CreateNativePixmap( ...@@ -160,7 +160,7 @@ scoped_refptr<gfx::NativePixmap> GbmSurfaceFactory::CreateNativePixmap(
} }
scoped_refptr<gfx::NativePixmap> scoped_refptr<gfx::NativePixmap>
GbmSurfaceFactory::CreateNativePixmapFromHandle( GbmSurfaceFactory::CreateNativePixmapFromHandleInternal(
gfx::AcceleratedWidget widget, gfx::AcceleratedWidget widget,
gfx::Size size, gfx::Size size,
gfx::BufferFormat format, gfx::BufferFormat format,
...@@ -176,7 +176,6 @@ GbmSurfaceFactory::CreateNativePixmapFromHandle( ...@@ -176,7 +176,6 @@ GbmSurfaceFactory::CreateNativePixmapFromHandle(
} }
std::vector<gfx::NativePixmapPlane> planes; std::vector<gfx::NativePixmapPlane> planes;
for (const auto& plane : handle.planes) { for (const auto& plane : handle.planes) {
planes.push_back(plane); planes.push_back(plane);
} }
...@@ -185,7 +184,44 @@ GbmSurfaceFactory::CreateNativePixmapFromHandle( ...@@ -185,7 +184,44 @@ GbmSurfaceFactory::CreateNativePixmapFromHandle(
widget, size, format, std::move(scoped_fds), planes); widget, size, format, std::move(scoped_fds), planes);
if (!buffer) if (!buffer)
return nullptr; return nullptr;
return base::MakeRefCounted<GbmPixmap>(this, buffer); return base::MakeRefCounted<GbmPixmap>(this, buffer);
} }
scoped_refptr<gfx::NativePixmap>
GbmSurfaceFactory::CreateNativePixmapFromHandle(
gfx::AcceleratedWidget widget,
gfx::Size size,
gfx::BufferFormat format,
const gfx::NativePixmapHandle& handle) {
// Query the external service (if available), whether it recognizes this
// NativePixmapHandle, and whether it can provide a corresponding NativePixmap
// backing it. If so, the handle is consumed. Otherwise, the handle remains
// valid and can be further importer by standard means.
if (!get_protected_native_pixmap_callback_.is_null()) {
auto protected_pixmap = get_protected_native_pixmap_callback_.Run(handle);
if (protected_pixmap)
return protected_pixmap;
}
return CreateNativePixmapFromHandleInternal(widget, size, format, handle);
}
scoped_refptr<gfx::NativePixmap>
GbmSurfaceFactory::CreateNativePixmapForProtectedBufferHandle(
gfx::AcceleratedWidget widget,
gfx::Size size,
gfx::BufferFormat format,
const gfx::NativePixmapHandle& handle) {
// Create a new NativePixmap without querying the external service for any
// existing mappings.
return CreateNativePixmapFromHandleInternal(widget, size, format, handle);
}
void GbmSurfaceFactory::SetGetProtectedNativePixmapDelegate(
const GetProtectedNativePixmapCallback&
get_protected_native_pixmap_callback) {
get_protected_native_pixmap_callback_ = get_protected_native_pixmap_callback;
}
} // namespace ui } // namespace ui
...@@ -50,8 +50,22 @@ class GbmSurfaceFactory : public SurfaceFactoryOzone { ...@@ -50,8 +50,22 @@ class GbmSurfaceFactory : public SurfaceFactoryOzone {
gfx::Size size, gfx::Size size,
gfx::BufferFormat format, gfx::BufferFormat format,
const gfx::NativePixmapHandle& handle) override; const gfx::NativePixmapHandle& handle) override;
void SetGetProtectedNativePixmapDelegate(
const GetProtectedNativePixmapCallback&
get_protected_native_pixmap_callback) override;
scoped_refptr<gfx::NativePixmap> CreateNativePixmapForProtectedBufferHandle(
gfx::AcceleratedWidget widget,
gfx::Size size,
gfx::BufferFormat format,
const gfx::NativePixmapHandle& handle) override;
private: private:
scoped_refptr<gfx::NativePixmap> CreateNativePixmapFromHandleInternal(
gfx::AcceleratedWidget widget,
gfx::Size size,
gfx::BufferFormat format,
const gfx::NativePixmapHandle& handle);
std::unique_ptr<GLOzone> egl_implementation_; std::unique_ptr<GLOzone> egl_implementation_;
std::unique_ptr<GLOzone> osmesa_implementation_; std::unique_ptr<GLOzone> osmesa_implementation_;
...@@ -61,6 +75,8 @@ class GbmSurfaceFactory : public SurfaceFactoryOzone { ...@@ -61,6 +75,8 @@ class GbmSurfaceFactory : public SurfaceFactoryOzone {
std::map<gfx::AcceleratedWidget, GbmSurfaceless*> widget_to_surface_map_; std::map<gfx::AcceleratedWidget, GbmSurfaceless*> widget_to_surface_map_;
GetProtectedNativePixmapCallback get_protected_native_pixmap_callback_;
DISALLOW_COPY_AND_ASSIGN(GbmSurfaceFactory); DISALLOW_COPY_AND_ASSIGN(GbmSurfaceFactory);
}; };
......
...@@ -83,6 +83,7 @@ class TestPixmap : public gfx::NativePixmap { ...@@ -83,6 +83,7 @@ class TestPixmap : public gfx::NativePixmap {
uint64_t GetDmaBufModifier(size_t plane) const override { return 0; } uint64_t GetDmaBufModifier(size_t plane) const override { return 0; }
gfx::BufferFormat GetBufferFormat() const override { return format_; } gfx::BufferFormat GetBufferFormat() const override { return format_; }
gfx::Size GetBufferSize() const override { return gfx::Size(); } gfx::Size GetBufferSize() const override { return gfx::Size(); }
uint32_t GetUniqueId() const override { return 0; }
bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget, bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget,
int plane_z_order, int plane_z_order,
gfx::OverlayTransform plane_transform, gfx::OverlayTransform plane_transform,
......
...@@ -52,4 +52,17 @@ SurfaceFactoryOzone::CreateNativePixmapFromHandle( ...@@ -52,4 +52,17 @@ SurfaceFactoryOzone::CreateNativePixmapFromHandle(
return nullptr; return nullptr;
} }
scoped_refptr<gfx::NativePixmap>
SurfaceFactoryOzone::CreateNativePixmapForProtectedBufferHandle(
gfx::AcceleratedWidget widget,
gfx::Size size,
gfx::BufferFormat format,
const gfx::NativePixmapHandle& handle) {
return nullptr;
}
void SurfaceFactoryOzone::SetGetProtectedNativePixmapDelegate(
const GetProtectedNativePixmapCallback&
get_protected_native_pixmap_callback) {}
} // namespace ui } // namespace ui
...@@ -99,6 +99,38 @@ class OZONE_BASE_EXPORT SurfaceFactoryOzone { ...@@ -99,6 +99,38 @@ class OZONE_BASE_EXPORT SurfaceFactoryOzone {
gfx::BufferFormat format, gfx::BufferFormat format,
const gfx::NativePixmapHandle& handle); const gfx::NativePixmapHandle& handle);
// A temporary solution that allows protected NativePixmap management to be
// handled outside the Ozone platform (crbug.com/771863).
// The current implementation uses dummy NativePixmaps as transparent handles
// to separate NativePixmaps with actual contents. This method takes
// a NativePixmapHandle to such a dummy pixmap, and creates a NativePixmap
// instance for it.
virtual scoped_refptr<gfx::NativePixmap>
CreateNativePixmapForProtectedBufferHandle(
gfx::AcceleratedWidget widget,
gfx::Size size,
gfx::BufferFormat format,
const gfx::NativePixmapHandle& handle);
// This callback can be used by implementations of this interface to query
// for a NativePixmap for the given NativePixmapHandle, instead of importing
// it via standard means. This happens if an external service is maintaining
// a separate mapping of NativePixmapHandles to NativePixmaps.
// If this callback returns non-nullptr, the returned NativePixmap should
// be used instead of the NativePixmap that would have been produced by the
// standard, implementation-specific NativePixmapHandle import mechanism.
using GetProtectedNativePixmapCallback =
base::Callback<scoped_refptr<gfx::NativePixmap>(
const gfx::NativePixmapHandle&)>;
// Called by an external service to set the GetProtectedNativePixmapCallback,
// to be used by the implementation when importing NativePixmapHandles.
// TODO(posciak): crbug.com/778555, move this to platform-specific
// implementation(s) and make protected pixmap handling transparent to the
// clients of this interface, removing the need for this callback.
virtual void SetGetProtectedNativePixmapDelegate(
const GetProtectedNativePixmapCallback&
get_protected_native_pixmap_callback);
protected: protected:
SurfaceFactoryOzone(); SurfaceFactoryOzone();
virtual ~SurfaceFactoryOzone(); virtual ~SurfaceFactoryOzone();
......
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