Commit c94a5189 authored by Antoine Labour's avatar Antoine Labour Committed by Commit Bot

Add SharedImageInterface, Proxy, and Stub.

SharedImageInterface is a minimal interface to allocate and destroy
mailbox resources. It is independent of GL, stateless, thread-safe and
expresses direct ownership of the resources.
SharedImageInterfaceProxy and SharedImageStub implement
SharedImageInterface over IPC.

Note: currently SharedImageInterfaceProxy sends an IPC for creating and
destroying shared images, but this will be merged into the multi-flush
IPC in a follow-up.

Bug: 870116
Cq-Include-Trybots: luci.chromium.try:android_optional_gpu_tests_rel;luci.chromium.try:linux_optional_gpu_tests_rel;luci.chromium.try:mac_optional_gpu_tests_rel;luci.chromium.try:win_optional_gpu_tests_rel
Change-Id: I8f0b86957fab34a1a93f0b2ada8590a048e81724
Reviewed-on: https://chromium-review.googlesource.com/1164168
Commit-Queue: Antoine Labour <piman@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Reviewed-by: default avatarVictor Miura <vmiura@chromium.org>
Cr-Commit-Position: refs/heads/master@{#582203}
parent 666efbc2
......@@ -6,13 +6,18 @@ import("//components/viz/viz.gni")
import("//testing/test.gni")
import("//gpu/vulkan/features.gni")
viz_component("resource_format") {
output_name = "viz_resource_format"
source_set("resource_format") {
sources = [
"resources/resource_format.h",
]
}
viz_component("resource_format_utils") {
output_name = "viz_resource_format_utils"
defines = [ "VIZ_RESOURCE_FORMAT_IMPLEMENTATION" ]
sources = [
"resources/resource_format.h",
"resources/resource_format_utils.cc",
"resources/resource_format_utils.h",
"viz_resource_format_export.h",
......@@ -20,6 +25,10 @@ viz_component("resource_format") {
configs = [ "//third_party/khronos:khronos_headers" ]
public_deps = [
":resource_format",
]
deps = [
"//base",
"//skia",
......@@ -188,7 +197,7 @@ viz_component("common") {
}
public_deps = [
":resource_format",
":resource_format_utils",
"//gpu/command_buffer/client",
"//gpu/command_buffer/common",
"//mojo/public/cpp/bindings",
......
......@@ -62,6 +62,7 @@ source_set("client_sources") {
"mapped_memory.h",
"ring_buffer.cc",
"ring_buffer.h",
"shared_image_interface.h",
"transfer_buffer.cc",
"transfer_buffer.h",
]
......@@ -72,6 +73,7 @@ source_set("client_sources") {
public_deps = [
"//base",
"//components/viz/common:resource_format",
]
deps = [
"//gpu/command_buffer/common:common_sources",
......@@ -209,7 +211,7 @@ source_set("raster_sources") {
":raster_interface",
"//base",
"//cc/paint",
"//components/viz/common:resource_format",
"//components/viz/common:resource_format_utils",
"//gpu/command_buffer/common",
"//gpu/command_buffer/common:gles2",
"//gpu/command_buffer/common:gles2_utils",
......
// Copyright 2018 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 GPU_COMMAND_BUFFER_CLIENT_SHARED_IMAGE_INTERFACE_H_
#define GPU_COMMAND_BUFFER_CLIENT_SHARED_IMAGE_INTERFACE_H_
#include "base/compiler_specific.h"
#include "components/viz/common/resources/resource_format.h"
#include "gpu/command_buffer/common/mailbox.h"
#include "gpu/command_buffer/common/sync_token.h"
namespace gfx {
class Size;
class ColorSpace;
} // namespace gfx
namespace gpu {
// An interface to create shared images that can be imported into other APIs.
// This interface is thread-safe and (essentially) stateless. It is asynchronous
// in the same sense as GLES2Interface or RasterInterface in that commands are
// executed asynchronously on the service side, but can be synchronized using
// SyncTokens. See //docs/design/gpu_synchronization.md.
class SharedImageInterface {
public:
virtual ~SharedImageInterface() {}
// Creates a shared image of requested |format|, |size| and |color_space|.
// |usage| is a combination of |SharedImageUsage| bits that describes which
// API(s) the image will be used with.
// Returns a mailbox that can be imported into said APIs using their
// corresponding mailbox functions (e.g.
// RasterInterface::CreateAndConsumeTexture or
// GLES2Interface::CreateAndConsumeTextureCHROMIUM).
// The |SharedImageInterface| keeps ownership of the image until
// |DestroySharedImage| is called or the interface itself is destroyed (e.g.
// the GPU channel is lost).
virtual Mailbox CreateSharedImage(viz::ResourceFormat format,
const gfx::Size& size,
const gfx::ColorSpace& color_space,
uint32_t usage) = 0;
// Destroys the shared image, unregistering its mailbox, after |sync_token|
// has been released. After this call, the mailbox can't be used to reference
// the image any more, however if the image was imported into other APIs,
// those may keep a reference to the underlying data.
virtual void DestroySharedImage(const SyncToken& sync_token,
const Mailbox& mailbox) = 0;
// Generates an unverified SyncToken that is released after all previous
// commands on this interface have executed on the service side.
virtual SyncToken GenUnverifiedSyncToken() = 0;
};
} // namespace gpu
#endif // GPU_COMMAND_BUFFER_CLIENT_SHARED_IMAGE_INTERFACE_H_
......@@ -253,6 +253,7 @@ target(link_target_type, "gles2_sources") {
"//base",
"//base/third_party/dynamic_annotations",
"//cc/paint",
"//components/viz/common:resource_format_utils",
"//gpu/command_buffer/client",
"//gpu/command_buffer/common:gles2_utils",
"//gpu/config",
......
......@@ -22,6 +22,8 @@ source_set("ipc_client_sources") {
"command_buffer_proxy_impl.h",
"gpu_channel_host.cc",
"gpu_channel_host.h",
"shared_image_interface_proxy.cc",
"shared_image_interface_proxy.h",
]
configs += [
"//build/config/compiler:no_size_t_to_int_warning",
......
......@@ -26,6 +26,7 @@
#include "gpu/command_buffer/common/gpu_memory_buffer_support.h"
#include "gpu/command_buffer/common/sync_token.h"
#include "gpu/ipc/client/gpu_channel_host.h"
#include "gpu/ipc/common/command_buffer_id.h"
#include "gpu/ipc/common/gpu_messages.h"
#include "gpu/ipc/common/gpu_param_traits.h"
#include "mojo/public/cpp/system/buffer.h"
......@@ -36,19 +37,6 @@
namespace gpu {
namespace {
gpu::CommandBufferId CommandBufferProxyID(int channel_id, int32_t route_id) {
return gpu::CommandBufferId::FromUnsafeValue(
(static_cast<uint64_t>(channel_id) << 32) | route_id);
}
int GetChannelID(gpu::CommandBufferId command_buffer_id) {
return static_cast<int>(command_buffer_id.GetUnsafeValue() >> 32);
}
} // namespace
CommandBufferProxyImpl::CommandBufferProxyImpl(
scoped_refptr<GpuChannelHost> channel,
GpuMemoryBufferManager* gpu_memory_buffer_manager,
......@@ -59,7 +47,8 @@ CommandBufferProxyImpl::CommandBufferProxyImpl(
channel_id_(channel_->channel_id()),
route_id_(channel_->GenerateRouteID()),
stream_id_(stream_id),
command_buffer_id_(CommandBufferProxyID(channel_id_, route_id_)),
command_buffer_id_(
CommandBufferIdFromChannelAndRoute(channel_id_, route_id_)),
callback_thread_(std::move(task_runner)),
weak_ptr_factory_(this) {
DCHECK(route_id_);
......@@ -570,7 +559,8 @@ void CommandBufferProxyImpl::WaitSyncTokenHint(
bool CommandBufferProxyImpl::CanWaitUnverifiedSyncToken(
const gpu::SyncToken& sync_token) {
// Can only wait on an unverified sync token if it is from the same channel.
int sync_token_channel_id = GetChannelID(sync_token.command_buffer_id());
int sync_token_channel_id =
ChannelIdFromCommandBufferId(sync_token.command_buffer_id());
if (sync_token.namespace_id() != gpu::CommandBufferNamespace::GPU_IO ||
sync_token_channel_id != channel_id_) {
return false;
......
......@@ -14,6 +14,7 @@
#include "base/threading/thread_task_runner_handle.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "gpu/ipc/common/command_buffer_id.h"
#include "gpu/ipc/common/gpu_messages.h"
#include "gpu/ipc/common/gpu_param_traits_macros.h"
#include "ipc/ipc_channel_mojo.h"
......@@ -41,7 +42,9 @@ GpuChannelHost::GpuChannelHost(int channel_id,
listener_(new Listener(std::move(handle), io_thread_),
base::OnTaskRunnerDeleter(io_thread_)) {
next_image_id_.GetNext();
next_route_id_.GetNext();
for (int32_t i = 0;
i <= static_cast<int32_t>(GpuChannelReservedRoutes::kMaxValue); ++i)
next_route_id_.GetNext();
}
bool GpuChannelHost::Send(IPC::Message* msg) {
......
// Copyright 2018 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 "gpu/ipc/client/shared_image_interface_proxy.h"
#include "gpu/ipc/client/gpu_channel_host.h"
#include "gpu/ipc/common/command_buffer_id.h"
#include "gpu/ipc/common/gpu_messages.h"
#include "gpu/ipc/common/gpu_param_traits_macros.h"
namespace gpu {
SharedImageInterfaceProxy::SharedImageInterfaceProxy(GpuChannelHost* host,
int32_t route_id)
: host_(host), route_id_(route_id) {}
SharedImageInterfaceProxy::~SharedImageInterfaceProxy() = default;
Mailbox SharedImageInterfaceProxy::CreateSharedImage(
viz::ResourceFormat format,
const gfx::Size& size,
const gfx::ColorSpace& color_space,
uint32_t usage) {
GpuChannelMsg_CreateSharedImage_Params params;
params.mailbox = Mailbox::Generate();
params.format = format;
params.size = size;
params.color_space = color_space;
params.usage = usage;
{
base::AutoLock lock(lock_);
params.release_id = ++next_release_id_;
// Note: we send the IPC under the lock to guarantee monotonicity of the
// release ids as seen by the service.
// TODO(piman): send this via GpuChannelMsg_FlushCommandBuffers
host_->Send(new GpuChannelMsg_CreateSharedImage(route_id_, params));
}
return params.mailbox;
}
void SharedImageInterfaceProxy::DestroySharedImage(const SyncToken& sync_token,
const Mailbox& mailbox) {
if (sync_token.verified_flush()) {
// TODO(piman): send this via GpuChannelMsg_FlushCommandBuffers
host_->Send(new GpuChannelMsg_DestroySharedImage(0, sync_token, mailbox));
return;
}
// Only allow unverified sync tokens for the same channel.
DCHECK_EQ(sync_token.namespace_id(), gpu::CommandBufferNamespace::GPU_IO);
int sync_token_channel_id =
ChannelIdFromCommandBufferId(sync_token.command_buffer_id());
DCHECK_EQ(sync_token_channel_id, host_->channel_id());
host_->EnsureFlush(UINT32_MAX);
SyncToken new_token = sync_token;
new_token.SetVerifyFlush();
host_->Send(
new GpuChannelMsg_DestroySharedImage(route_id_, new_token, mailbox));
}
SyncToken SharedImageInterfaceProxy::GenUnverifiedSyncToken() {
base::AutoLock lock(lock_);
return SyncToken(
CommandBufferNamespace::GPU_IO,
CommandBufferIdFromChannelAndRoute(host_->channel_id(), route_id_),
next_release_id_);
}
} // namespace gpu
// Copyright 2018 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 GPU_IPC_CLIENT_SHARED_IMAGE_INTERFACE_PROXY_H_
#define GPU_IPC_CLIENT_SHARED_IMAGE_INTERFACE_PROXY_H_
#include "base/synchronization/lock.h"
#include "gpu/command_buffer/client/shared_image_interface.h"
namespace gpu {
class GpuChannelHost;
// Implementation of SharedImageInterface that sends commands over GPU channel
// IPCs.
class SharedImageInterfaceProxy : public SharedImageInterface {
public:
explicit SharedImageInterfaceProxy(GpuChannelHost* host, int32_t route_id);
~SharedImageInterfaceProxy() override;
Mailbox CreateSharedImage(viz::ResourceFormat format,
const gfx::Size& size,
const gfx::ColorSpace& color_space,
uint32_t usage) override;
void DestroySharedImage(const SyncToken& sync_token,
const Mailbox& mailbox) override;
SyncToken GenUnverifiedSyncToken() override;
private:
GpuChannelHost* const host_;
const int32_t route_id_;
// Protects next_release_id_.
base::Lock lock_;
uint32_t next_release_id_ = 0;
};
} // namespace gpu
#endif // GPU_IPC_CLIENT_SHARED_IMAGE_INTERFACE_PROXY_H_
......@@ -65,6 +65,7 @@ source_set("ipc_common_sources") {
visibility = [ "//gpu/*" ]
sources = [
"command_buffer_id.h",
"flush_params.cc",
"flush_params.h",
"gpu_client_ids.h",
......@@ -125,11 +126,13 @@ source_set("ipc_common_sources") {
deps = [
"//base",
"//components/viz/common:resource_format",
"//gpu/command_buffer/common:common_sources",
"//gpu/config:config_sources",
"//ui/base",
"//ui/gfx/ipc",
"//ui/gfx/ipc/buffer_types",
"//ui/gfx/ipc/color",
"//ui/gfx/ipc/geometry",
"//ui/gl",
]
......
include_rules = [
"+base",
"+components/viz/common/resources/resource_format.h",
"+ipc",
"+mojo",
"+ui/base",
......
// Copyright 2018 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 GPU_IPC_COMMON_COMMAND_BUFFER_ID_H_
#define GPU_IPC_COMMON_COMMAND_BUFFER_ID_H_
#include "gpu/command_buffer/common/command_buffer_id.h"
namespace gpu {
enum class GpuChannelReservedRoutes : int32_t {
kSharedImageInterface = 0,
kMaxValue = kSharedImageInterface,
};
inline CommandBufferId CommandBufferIdFromChannelAndRoute(int channel_id,
int32_t route_id) {
return CommandBufferId::FromUnsafeValue(
(static_cast<uint64_t>(channel_id) << 32) | route_id);
}
inline int ChannelIdFromCommandBufferId(
gpu::CommandBufferId command_buffer_id) {
return static_cast<int>(command_buffer_id.GetUnsafeValue() >> 32);
}
} // namespace gpu
#endif // GPU_IPC_COMMON_COMMAND_BUFFER_ID_H_
......@@ -16,6 +16,7 @@
#include "base/memory/shared_memory.h"
#include "base/unguessable_token.h"
#include "build/build_config.h"
#include "components/viz/common/resources/resource_format.h"
#include "gpu/command_buffer/common/capabilities.h"
#include "gpu/command_buffer/common/command_buffer.h"
#include "gpu/command_buffer/common/constants.h"
......@@ -32,6 +33,7 @@
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/gpu_fence_handle.h"
#include "ui/gfx/gpu_memory_buffer.h"
#include "ui/gfx/ipc/color/gfx_param_traits.h"
#include "ui/gfx/ipc/geometry/gfx_param_traits.h"
#include "ui/gfx/ipc/gfx_param_traits.h"
#include "ui/gfx/native_widget_types.h"
......@@ -72,6 +74,15 @@ IPC_STRUCT_BEGIN(GpuCommandBufferMsg_CreateImage_Params)
IPC_STRUCT_MEMBER(uint64_t, image_release_count)
IPC_STRUCT_END()
IPC_STRUCT_BEGIN(GpuChannelMsg_CreateSharedImage_Params)
IPC_STRUCT_MEMBER(gpu::Mailbox, mailbox)
IPC_STRUCT_MEMBER(viz::ResourceFormat, format)
IPC_STRUCT_MEMBER(gfx::Size, size)
IPC_STRUCT_MEMBER(gfx::ColorSpace, color_space)
IPC_STRUCT_MEMBER(uint32_t, usage)
IPC_STRUCT_MEMBER(uint32_t, release_id)
IPC_STRUCT_END()
//------------------------------------------------------------------------------
// GPU Channel Messages
// These are messages from a renderer process to the GPU process.
......@@ -97,6 +108,12 @@ IPC_SYNC_MESSAGE_CONTROL1_0(GpuChannelMsg_DestroyCommandBuffer,
IPC_MESSAGE_CONTROL1(GpuChannelMsg_FlushCommandBuffers,
std::vector<gpu::FlushParams> /* flush_list */)
IPC_MESSAGE_ROUTED1(GpuChannelMsg_CreateSharedImage,
GpuChannelMsg_CreateSharedImage_Params /* params */)
IPC_MESSAGE_ROUTED2(GpuChannelMsg_DestroySharedImage,
gpu::SyncToken /* sync_token */,
gpu::Mailbox /* id */)
// Crash the GPU process in similar way to how chrome://gpucrash does.
// This is only supported in testing environments, and is otherwise ignored.
IPC_MESSAGE_CONTROL0(GpuChannelMsg_CrashForTesting)
......
......@@ -5,6 +5,7 @@
#ifndef GPU_IPC_COMMON_GPU_PARAM_TRAITS_MACROS_H_
#define GPU_IPC_COMMON_GPU_PARAM_TRAITS_MACROS_H_
#include "components/viz/common/resources/resource_format.h"
#include "gpu/command_buffer/common/constants.h"
#include "gpu/command_buffer/common/context_result.h"
#include "gpu/command_buffer/common/scheduling_priority.h"
......@@ -38,4 +39,6 @@ IPC_STRUCT_TRAITS_BEGIN(gpu::SwapBuffersCompleteParams)
IPC_STRUCT_TRAITS_MEMBER(swap_response)
IPC_STRUCT_TRAITS_END()
IPC_ENUM_TRAITS_MAX_VALUE(viz::ResourceFormat, viz::RESOURCE_FORMAT_MAX);
#endif // GPU_IPC_COMMON_GPU_PARAM_TRAITS_MACROS_H_
......@@ -34,6 +34,8 @@ component("service") {
"pass_through_image_transport_surface.h",
"raster_command_buffer_stub.cc",
"raster_command_buffer_stub.h",
"shared_image_stub.cc",
"shared_image_stub.h",
]
defines = [ "GPU_IPC_SERVICE_IMPLEMENTATION" ]
if (is_chromecast) {
......
include_rules = [
"+components/viz/common/features.h",
"+components/viz/common/resources/resource_format.h",
"+third_party/skia",
"+ui/accelerated_widget_mac",
"+ui/base",
......
......@@ -37,6 +37,7 @@
#include "gpu/command_buffer/service/mailbox_manager.h"
#include "gpu/command_buffer/service/memory_tracking.h"
#include "gpu/command_buffer/service/scheduler.h"
#include "gpu/ipc/common/command_buffer_id.h"
#include "gpu/ipc/common/gpu_messages.h"
#include "gpu/ipc/service/gles2_command_buffer_stub.h"
#include "gpu/ipc/service/gpu_channel_manager.h"
......@@ -51,14 +52,6 @@
#include "ui/gl/gl_utils.h"
namespace gpu {
namespace {
CommandBufferId GenerateCommandBufferId(int channel_id, int32_t route_id) {
return CommandBufferId::FromUnsafeValue(
(static_cast<uint64_t>(channel_id) << 32) | route_id);
}
} // anonymous namespace
struct GpuChannelMessage {
IPC::Message message;
......@@ -296,12 +289,21 @@ bool GpuChannelMessageFilter::OnMessageReceived(const IPC::Message& message) {
auto it = route_sequences_.find(message.routing_id());
if (it == route_sequences_.end())
return MessageErrorHandler(message, "Invalid route id");
std::vector<SyncToken> tokens;
if (message.type() == GpuChannelMsg_DestroySharedImage::ID) {
GpuChannelMsg_DestroySharedImage::Param params;
if (!GpuChannelMsg_DestroySharedImage::Read(&message, &params)) {
return MessageErrorHandler(message,
"Invalid DestroySharedImage message");
}
tokens.push_back(std::get<0>(params));
}
scheduler_->ScheduleTask(
Scheduler::Task(it->second /* sequence_id */,
base::BindOnce(&GpuChannel::HandleMessage,
gpu_channel_->AsWeakPtr(), message),
std::vector<SyncToken>()));
std::move(tokens)));
}
return true;
......@@ -391,6 +393,13 @@ GpuChannel::~GpuChannel() {
void GpuChannel::Init(std::unique_ptr<FilteredSender> channel) {
channel_ = std::move(channel);
channel_->AddFilter(filter_.get());
// SharedImageInterfaceProxy/Stub is a singleton per channel, using a reserved
// route.
const int32_t route_id =
static_cast<int32_t>(GpuChannelReservedRoutes::kSharedImageInterface);
shared_image_stub_ = std::make_unique<SharedImageStub>(this, route_id);
filter_->AddRoute(route_id, shared_image_stub_->sequence());
router_.AddRoute(route_id, shared_image_stub_.get());
}
void GpuChannel::SetUnhandledMessageListener(IPC::Listener* listener) {
......@@ -618,7 +627,7 @@ void GpuChannel::OnCreateCommandBuffer(
}
CommandBufferId command_buffer_id =
GenerateCommandBufferId(client_id_, route_id);
CommandBufferIdFromChannelAndRoute(client_id_, route_id);
SequenceId sequence_id = stream_sequences_[stream_id];
if (sequence_id.is_null()) {
......@@ -722,6 +731,7 @@ uint64_t GpuChannel::GetMemoryUsage() const {
}
size += tracker->GetSize();
}
size += shared_image_stub_->GetSize();
return size;
}
......
......@@ -11,6 +11,7 @@
#include <memory>
#include <string>
#include "base/callback.h"
#include "base/containers/flat_map.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
......@@ -23,6 +24,7 @@
#include "gpu/command_buffer/service/sync_point_manager.h"
#include "gpu/ipc/service/command_buffer_stub.h"
#include "gpu/ipc/service/gpu_ipc_service_export.h"
#include "gpu/ipc/service/shared_image_stub.h"
#include "ipc/ipc_sender.h"
#include "ipc/ipc_sync_channel.h"
#include "ipc/message_router.h"
......@@ -39,10 +41,11 @@ class WaitableEvent;
namespace gpu {
class Scheduler;
class SyncPointManager;
class GpuChannelManager;
class GpuChannelMessageFilter;
class Scheduler;
class SharedImageStub;
class SyncPointManager;
class GPU_IPC_SERVICE_EXPORT FilteredSender : public IPC::Sender {
public:
......@@ -237,6 +240,7 @@ class GPU_IPC_SERVICE_EXPORT GpuChannel : public IPC::Listener,
scoped_refptr<gl::GLShareGroup> share_group_;
std::unique_ptr<gles2::ImageManager> image_manager_;
std::unique_ptr<SharedImageStub> shared_image_stub_;
const bool is_gpu_host_;
......
// Copyright 2018 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 "gpu/ipc/service/shared_image_stub.h"
#include "gpu/command_buffer/service/scheduler.h"
#include "gpu/command_buffer/service/shared_image_factory.h"
#include "gpu/ipc/common/command_buffer_id.h"
#include "gpu/ipc/common/gpu_messages.h"
#include "gpu/ipc/service/gpu_channel.h"
#include "gpu/ipc/service/gpu_channel_manager.h"
#include "gpu/ipc/service/gpu_memory_buffer_factory.h"
#include "ui/gl/gl_context.h"
namespace gpu {
SharedImageStub::SharedImageStub(GpuChannel* channel, int32_t route_id)
: channel_(channel),
sequence_(channel->scheduler()->CreateSequence(SchedulingPriority::kLow)),
sync_point_client_state_(
channel->sync_point_manager()->CreateSyncPointClientState(
CommandBufferNamespace::GPU_IO,
CommandBufferIdFromChannelAndRoute(channel->client_id(),
route_id),
sequence_)) {}
SharedImageStub::~SharedImageStub() {
channel_->scheduler()->DestroySequence(sequence_);
sync_point_client_state_->Destroy();
if (factory_ && factory_->HasImages()) {
bool have_context = MakeContextCurrentAndCreateFactory();
factory_->DestroyAllSharedImages(have_context);
}
}
bool SharedImageStub::OnMessageReceived(const IPC::Message& msg) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(SharedImageStub, msg)
IPC_MESSAGE_HANDLER(GpuChannelMsg_CreateSharedImage, OnCreateSharedImage)
IPC_MESSAGE_HANDLER(GpuChannelMsg_DestroySharedImage, OnDestroySharedImage)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
}
void SharedImageStub::OnCreateSharedImage(
const GpuChannelMsg_CreateSharedImage_Params& params) {
if (!MakeContextCurrentAndCreateFactory())
return;
if (!factory_->CreateSharedImage(params.mailbox, params.format, params.size,
params.color_space, params.usage)) {
LOG(ERROR) << "SharedImageStub: Unable to create shared image";
OnError();
return;
}
sync_point_client_state_->ReleaseFenceSync(params.release_id);
}
void SharedImageStub::OnDestroySharedImage(const gpu::SyncToken& sync_token,
const Mailbox& mailbox) {
// The Scheduler guaranteed this only executes after the sync_token was
// released.
DCHECK(channel_->sync_point_manager()->IsSyncTokenReleased(sync_token));
if (!MakeContextCurrentAndCreateFactory())
return;
if (!factory_->DestroySharedImage(mailbox)) {
LOG(ERROR) << "SharedImageStub: Unable to destroy shared image";
OnError();
return;
}
}
bool SharedImageStub::MakeContextCurrentAndCreateFactory() {
if (!factory_) {
auto* channel_manager = channel_->gpu_channel_manager();
DCHECK(!context_state_);
ContextResult result;
context_state_ = channel_manager->GetRasterDecoderContextState(&result);
if (result != ContextResult::kSuccess) {
LOG(ERROR) << "SharedImageStub: unable to create context";
OnError();
return false;
}
DCHECK(context_state_);
DCHECK(!context_state_->context_lost);
DCHECK(context_state_->context->IsCurrent(nullptr));
gpu::GpuMemoryBufferFactory* gmb_factory =
channel_manager->gpu_memory_buffer_factory();
factory_ = std::make_unique<SharedImageFactory>(
channel_manager->gpu_preferences(),
channel_manager->gpu_driver_bug_workarounds(),
channel_manager->gpu_feature_info(), channel_manager->mailbox_manager(),
gmb_factory ? gmb_factory->AsImageFactory() : nullptr, this);
return true;
} else {
DCHECK(context_state_);
if (context_state_->context_lost) {
LOG(ERROR) << "SharedImageStub: context already lost";
OnError();
return false;
} else {
if (context_state_->context->MakeCurrent(context_state_->surface.get()))
return true;
context_state_->context_lost = true;
LOG(ERROR) << "SharedImageStub: MakeCurrent failed";
OnError();
return false;
}
}
}
void SharedImageStub::OnError() {
channel_->OnChannelError();
}
void SharedImageStub::TrackMemoryAllocatedChange(uint64_t delta) {
size_ += delta;
}
uint64_t SharedImageStub::GetSize() const {
return size_;
}
uint64_t SharedImageStub::ClientTracingId() const {
return channel_->client_tracing_id();
}
int SharedImageStub::ClientId() const {
return channel_->client_id();
}
uint64_t SharedImageStub::ShareGroupTracingGUID() const {
return sync_point_client_state_->command_buffer_id().GetUnsafeValue();
}
} // namespace gpu
// Copyright 2018 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 GPU_IPC_SERVICE_SHARED_IMAGE_STUB_H_
#define GPU_IPC_SERVICE_SHARED_IMAGE_STUB_H_
#include "components/viz/common/resources/resource_format.h"
#include "gpu/command_buffer/service/memory_tracking.h"
#include "gpu/command_buffer/service/sync_point_manager.h"
#include "ipc/ipc_listener.h"
struct GpuChannelMsg_CreateSharedImage_Params;
namespace gpu {
struct Mailbox;
class GpuChannel;
class SharedImageFactory;
namespace raster {
struct RasterDecoderContextState;
}
class SharedImageStub : public IPC::Listener, public gles2::MemoryTracker {
public:
SharedImageStub(GpuChannel* channel, int32_t route_id);
~SharedImageStub() override;
// IPC::Listener implementation:
bool OnMessageReceived(const IPC::Message& msg) override;
// gles2::MemoryTracker implementation;
void TrackMemoryAllocatedChange(uint64_t delta) override;
uint64_t GetSize() const override;
uint64_t ClientTracingId() const override;
int ClientId() const override;
uint64_t ShareGroupTracingGUID() const override;
SequenceId sequence() const { return sequence_; }
private:
void OnCreateSharedImage(
const GpuChannelMsg_CreateSharedImage_Params& params);
void OnDestroySharedImage(const gpu::SyncToken& sync_token,
const Mailbox& mailbox);
bool MakeContextCurrentAndCreateFactory();
void OnError();
GpuChannel* channel_;
SequenceId sequence_;
scoped_refptr<gpu::SyncPointClientState> sync_point_client_state_;
scoped_refptr<raster::RasterDecoderContextState> context_state_;
std::unique_ptr<SharedImageFactory> factory_;
uint64_t size_ = 0;
};
} // namespace gpu
#endif // GPU_IPC_SERVICE_SHARED_IMAGE_STUB_H_
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