diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-05-03 13:42:47 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-05-15 10:27:51 +0000 |
commit | 8c5c43c7b138c9b4b0bf56d946e61d3bbc111bec (patch) | |
tree | d29d987c4d7b173cf853279b79a51598f104b403 /chromium/gpu/ipc | |
parent | 830c9e163d31a9180fadca926b3e1d7dfffb5021 (diff) | |
download | qtwebengine-chromium-8c5c43c7b138c9b4b0bf56d946e61d3bbc111bec.tar.gz |
BASELINE: Update Chromium to 66.0.3359.156
Change-Id: I0c9831ad39911a086b6377b16f995ad75a51e441
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
Diffstat (limited to 'chromium/gpu/ipc')
38 files changed, 612 insertions, 512 deletions
diff --git a/chromium/gpu/ipc/client/command_buffer_proxy_impl.cc b/chromium/gpu/ipc/client/command_buffer_proxy_impl.cc index 8b2929b1ab3..7f60970a94b 100644 --- a/chromium/gpu/ipc/client/command_buffer_proxy_impl.cc +++ b/chromium/gpu/ipc/client/command_buffer_proxy_impl.cc @@ -4,6 +4,7 @@ #include "gpu/ipc/client/command_buffer_proxy_impl.h" +#include <memory> #include <utility> #include <vector> @@ -11,7 +12,6 @@ #include "base/command_line.h" #include "base/location.h" #include "base/logging.h" -#include "base/memory/ptr_util.h" #include "base/memory/shared_memory.h" #include "base/optional.h" #include "base/stl_util.h" @@ -234,9 +234,9 @@ void CommandBufferProxyImpl::OnSignalAck(uint32_t id, gpu::error::kLostContext); return; } - base::Closure callback = it->second; + base::OnceClosure callback = std::move(it->second); signal_tasks_.erase(it); - callback.Run(); + std::move(callback).Run(); } CommandBuffer::State CommandBufferProxyImpl::GetLastState() { @@ -575,7 +575,7 @@ bool CommandBufferProxyImpl::IsFenceSyncReleased(uint64_t release) { } void CommandBufferProxyImpl::SignalSyncToken(const gpu::SyncToken& sync_token, - const base::Closure& callback) { + base::OnceClosure callback) { CheckLock(); base::AutoLock lock(last_state_lock_); if (last_state_.error != gpu::error::kNoError) @@ -584,7 +584,7 @@ void CommandBufferProxyImpl::SignalSyncToken(const gpu::SyncToken& sync_token, uint32_t signal_id = next_signal_id_++; Send(new GpuCommandBufferMsg_SignalSyncToken(route_id_, sync_token, signal_id)); - signal_tasks_.insert(std::make_pair(signal_id, callback)); + signal_tasks_.insert(std::make_pair(signal_id, std::move(callback))); } void CommandBufferProxyImpl::WaitSyncTokenHint( @@ -614,7 +614,7 @@ void CommandBufferProxyImpl::SetSnapshotRequested() { } void CommandBufferProxyImpl::SignalQuery(uint32_t query, - const base::Closure& callback) { + base::OnceClosure callback) { CheckLock(); base::AutoLock lock(last_state_lock_); if (last_state_.error != gpu::error::kNoError) @@ -630,7 +630,7 @@ void CommandBufferProxyImpl::SignalQuery(uint32_t query, // called, leading to stalled threads and/or memory leaks. uint32_t signal_id = next_signal_id_++; Send(new GpuCommandBufferMsg_SignalQuery(route_id_, query, signal_id)); - signal_tasks_.insert(std::make_pair(signal_id, callback)); + signal_tasks_.insert(std::make_pair(signal_id, std::move(callback))); } void CommandBufferProxyImpl::CreateGpuFence(uint32_t gpu_fence_id, @@ -667,7 +667,7 @@ void CommandBufferProxyImpl::OnGetGpuFenceHandleComplete( uint32_t gpu_fence_id, const gfx::GpuFenceHandle& handle) { // Always consume the provided handle to avoid leaks on error. - auto gpu_fence = base::MakeUnique<gfx::GpuFence>(handle); + auto gpu_fence = std::make_unique<gfx::GpuFence>(handle); GetGpuFenceTaskMap::iterator it = get_gpu_fence_tasks_.find(gpu_fence_id); if (it == get_gpu_fence_tasks_.end()) { diff --git a/chromium/gpu/ipc/client/command_buffer_proxy_impl.h b/chromium/gpu/ipc/client/command_buffer_proxy_impl.h index afa5eb77e7f..5786d9cbde5 100644 --- a/chromium/gpu/ipc/client/command_buffer_proxy_impl.h +++ b/chromium/gpu/ipc/client/command_buffer_proxy_impl.h @@ -116,7 +116,7 @@ class GPU_EXPORT CommandBufferProxyImpl : public gpu::CommandBuffer, size_t height, unsigned internal_format) override; void DestroyImage(int32_t id) override; - void SignalQuery(uint32_t query, const base::Closure& callback) override; + void SignalQuery(uint32_t query, base::OnceClosure callback) override; void CreateGpuFence(uint32_t gpu_fence_id, ClientGpuFence source) override; void GetGpuFence(uint32_t gpu_fence_id, base::OnceCallback<void(std::unique_ptr<gfx::GpuFence>)> @@ -130,7 +130,7 @@ class GPU_EXPORT CommandBufferProxyImpl : public gpu::CommandBuffer, uint64_t GenerateFenceSyncRelease() override; bool IsFenceSyncReleased(uint64_t release) override; void SignalSyncToken(const gpu::SyncToken& sync_token, - const base::Closure& callback) override; + base::OnceClosure callback) override; void WaitSyncTokenHint(const gpu::SyncToken& sync_token) override; bool CanWaitUnverifiedSyncToken(const gpu::SyncToken& sync_token) override; void SetSnapshotRequested() override; @@ -172,7 +172,7 @@ class GPU_EXPORT CommandBufferProxyImpl : public gpu::CommandBuffer, private: typedef std::map<int32_t, scoped_refptr<gpu::Buffer>> TransferBufferMap; - typedef base::hash_map<uint32_t, base::Closure> SignalTaskMap; + typedef base::hash_map<uint32_t, base::OnceClosure> SignalTaskMap; void CheckLock() { if (lock_) { diff --git a/chromium/gpu/ipc/client/gpu_context_tests.h b/chromium/gpu/ipc/client/gpu_context_tests.h index 1118afd0463..b5b40cc4729 100644 --- a/chromium/gpu/ipc/client/gpu_context_tests.h +++ b/chromium/gpu/ipc/client/gpu_context_tests.h @@ -2,6 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#ifndef GPU_IPC_CLIENT_GPU_CONTEXT_TESTS_H_ +#define GPU_IPC_CLIENT_GPU_CONTEXT_TESTS_H_ + // These tests are run twice: // Once in a gpu test with an in-process command buffer. // Once in a browsertest with an out-of-process command buffer and gpu-process. @@ -197,3 +200,5 @@ CONTEXT_TEST_F(GpuFenceTest, BasicGpuFenceTest) { #endif // defined(OS_ANDROID) }; // namespace + +#endif // GPU_IPC_CLIENT_GPU_CONTEXT_TESTS_H_ diff --git a/chromium/gpu/ipc/client/gpu_memory_buffer_impl_android_hardware_buffer.cc b/chromium/gpu/ipc/client/gpu_memory_buffer_impl_android_hardware_buffer.cc index d85a90bf4a6..3242c742e0a 100644 --- a/chromium/gpu/ipc/client/gpu_memory_buffer_impl_android_hardware_buffer.cc +++ b/chromium/gpu/ipc/client/gpu_memory_buffer_impl_android_hardware_buffer.cc @@ -8,6 +8,7 @@ #include "base/android/android_hardware_buffer_compat.h" #include "base/bind.h" +#include "base/bind_helpers.h" #include "base/logging.h" #include "base/memory/ptr_util.h" #include "base/memory/shared_memory_handle.h" @@ -150,7 +151,7 @@ base::Closure GpuMemoryBufferImplAndroidHardwareBuffer::AllocateForTesting( DCHECK(buffer); handle->handle = base::SharedMemoryHandle(buffer, 0, base::UnguessableToken::Create()); - return base::Bind(&base::DoNothing); + return base::DoNothing(); } } // namespace gpu diff --git a/chromium/gpu/ipc/client/gpu_memory_buffer_impl_dxgi.cc b/chromium/gpu/ipc/client/gpu_memory_buffer_impl_dxgi.cc index 36ee720e877..43796ba66c3 100644 --- a/chromium/gpu/ipc/client/gpu_memory_buffer_impl_dxgi.cc +++ b/chromium/gpu/ipc/client/gpu_memory_buffer_impl_dxgi.cc @@ -5,6 +5,7 @@ #include <wrl.h> #include "base/bind.h" +#include "base/bind_helpers.h" #include "base/command_line.h" #include "base/memory/ptr_util.h" #include "gpu/ipc/client/gpu_memory_buffer_impl_dxgi.h" @@ -85,7 +86,7 @@ base::Closure GpuMemoryBufferImplDXGI::AllocateForTesting( base::UnguessableToken::Create()); handle->type = gfx::DXGI_SHARED_HANDLE; handle->id = kBufferId; - return base::Bind(&base::DoNothing); + return base::DoNothing(); } bool GpuMemoryBufferImplDXGI::Map() { diff --git a/chromium/gpu/ipc/client/gpu_memory_buffer_impl_io_surface.cc b/chromium/gpu/ipc/client/gpu_memory_buffer_impl_io_surface.cc index 40e592b900b..ae26b9e2f27 100644 --- a/chromium/gpu/ipc/client/gpu_memory_buffer_impl_io_surface.cc +++ b/chromium/gpu/ipc/client/gpu_memory_buffer_impl_io_surface.cc @@ -5,6 +5,8 @@ #include "gpu/ipc/client/gpu_memory_buffer_impl_io_surface.h" #include "base/bind.h" +#include "base/bind_helpers.h" +#include "base/debug/dump_without_crashing.h" #include "base/logging.h" #include "base/memory/ptr_util.h" #include "gpu/ipc/common/gpu_memory_buffer_support.h" @@ -14,6 +16,10 @@ namespace gpu { namespace { +// The maximum number of times to dump before throttling (to avoid sending +// thousands of crash dumps). +const int kMaxCrashDumps = 10; + uint32_t LockFlags(gfx::BufferUsage usage) { switch (usage) { case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE: @@ -30,8 +36,6 @@ uint32_t LockFlags(gfx::BufferUsage usage) { return 0; } -void NoOp() {} - } // namespace GpuMemoryBufferImplIOSurface::GpuMemoryBufferImplIOSurface( @@ -55,10 +59,22 @@ GpuMemoryBufferImplIOSurface::CreateFromHandle( gfx::BufferFormat format, gfx::BufferUsage usage, const DestructionCallback& callback) { + if (!handle.mach_port) { + LOG(ERROR) << "Invalid IOSurface mach port returned to client."; + return nullptr; + } + base::ScopedCFTypeRef<IOSurfaceRef> io_surface( IOSurfaceLookupFromMachPort(handle.mach_port.get())); - if (!io_surface) + if (!io_surface) { + LOG(ERROR) << "Failed to open IOSurface via mach port returned to client."; + static int dump_counter = kMaxCrashDumps; + if (dump_counter) { + dump_counter -= 1; + base::debug::DumpWithoutCrashing(); + } return nullptr; + } return base::WrapUnique( new GpuMemoryBufferImplIOSurface(handle.id, size, format, callback, @@ -85,7 +101,7 @@ base::Closure GpuMemoryBufferImplIOSurface::AllocateForTesting( handle->type = gfx::IO_SURFACE_BUFFER; handle->id = kBufferId; handle->mach_port.reset(IOSurfaceCreateMachPort(io_surface)); - return base::Bind(&NoOp); + return base::DoNothing(); } bool GpuMemoryBufferImplIOSurface::Map() { diff --git a/chromium/gpu/ipc/client/gpu_memory_buffer_impl_shared_memory.cc b/chromium/gpu/ipc/client/gpu_memory_buffer_impl_shared_memory.cc index 07506ca0553..2adc835aec7 100644 --- a/chromium/gpu/ipc/client/gpu_memory_buffer_impl_shared_memory.cc +++ b/chromium/gpu/ipc/client/gpu_memory_buffer_impl_shared_memory.cc @@ -8,6 +8,7 @@ #include <utility> #include "base/bind.h" +#include "base/bind_helpers.h" #include "base/format_macros.h" #include "base/memory/ptr_util.h" #include "base/numerics/safe_math.h" @@ -149,6 +150,7 @@ bool GpuMemoryBufferImplSharedMemory::IsSizeValidForFormat( case gfx::BufferFormat::BGRA_8888: case gfx::BufferFormat::BGRX_8888: case gfx::BufferFormat::BGRX_1010102: + case gfx::BufferFormat::RGBX_1010102: case gfx::BufferFormat::RGBA_F16: return true; case gfx::BufferFormat::YVU_420: @@ -176,7 +178,7 @@ base::Closure GpuMemoryBufferImplSharedMemory::AllocateForTesting( gfx::BufferUsage usage, gfx::GpuMemoryBufferHandle* handle) { *handle = CreateGpuMemoryBuffer(handle->id, size, format, usage); - return base::Bind(&base::DoNothing); + return base::DoNothing(); } bool GpuMemoryBufferImplSharedMemory::Map() { diff --git a/chromium/gpu/ipc/common/gpu_command_buffer_traits_multi.h b/chromium/gpu/ipc/common/gpu_command_buffer_traits_multi.h index 237dbd38f90..ea6796fff98 100644 --- a/chromium/gpu/ipc/common/gpu_command_buffer_traits_multi.h +++ b/chromium/gpu/ipc/common/gpu_command_buffer_traits_multi.h @@ -119,6 +119,8 @@ IPC_STRUCT_TRAITS_BEGIN(gpu::Capabilities) IPC_STRUCT_TRAITS_MEMBER(image_ycbcr_422) IPC_STRUCT_TRAITS_MEMBER(image_ycbcr_420v) IPC_STRUCT_TRAITS_MEMBER(image_ycbcr_420v_disabled_for_video_frames) + IPC_STRUCT_TRAITS_MEMBER(image_xr30) + IPC_STRUCT_TRAITS_MEMBER(image_xb30) IPC_STRUCT_TRAITS_MEMBER(render_buffer_format_bgra8888) IPC_STRUCT_TRAITS_MEMBER(occlusion_query) IPC_STRUCT_TRAITS_MEMBER(occlusion_query_boolean) @@ -138,6 +140,7 @@ IPC_STRUCT_TRAITS_BEGIN(gpu::Capabilities) IPC_STRUCT_TRAITS_MEMBER(texture_storage_image) IPC_STRUCT_TRAITS_MEMBER(supports_oop_raster) IPC_STRUCT_TRAITS_MEMBER(chromium_gpu_fence) + IPC_STRUCT_TRAITS_MEMBER(unpremultiply_and_dither_copy) IPC_STRUCT_TRAITS_MEMBER(major_version) IPC_STRUCT_TRAITS_MEMBER(minor_version) diff --git a/chromium/gpu/ipc/common/gpu_info.mojom b/chromium/gpu/ipc/common/gpu_info.mojom index bd27a69a558..5d9d4033a36 100644 --- a/chromium/gpu/ipc/common/gpu_info.mojom +++ b/chromium/gpu/ipc/common/gpu_info.mojom @@ -19,14 +19,6 @@ struct GpuDevice { string device_string; }; -// gpu::CollectInfoResult -enum CollectInfoResult { - kCollectInfoNone = 0, - kCollectInfoSuccess = 1, - kCollectInfoNonFatalFailure = 2, - kCollectInfoFatalFailure = 3 -}; - // gpu::VideoCodecProfile enum VideoCodecProfile { VIDEO_CODEC_PROFILE_UNKNOWN = -1, @@ -105,16 +97,13 @@ struct GpuInfo { bool software_rendering; bool direct_rendering; bool sandboxed; - int32 process_crash_count; bool in_process_gpu; bool passthrough_cmd_decoder; bool direct_composition; bool supports_overlays; bool can_support_threaded_texture_mailbox; - CollectInfoResult basic_info_state; - CollectInfoResult context_info_state; - CollectInfoResult dx_diagnostics_info_state; - DxDiagNode? dx_diagnostics; + [EnableIf=is_win] + DxDiagNode dx_diagnostics; VideoDecodeAcceleratorCapabilities video_decode_accelerator_capabilities; array<VideoEncodeAcceleratorSupportedProfile> video_encode_accelerator_supported_profiles; diff --git a/chromium/gpu/ipc/common/gpu_info_struct_traits.cc b/chromium/gpu/ipc/common/gpu_info_struct_traits.cc index 4ea3e562209..c97c165ab6c 100644 --- a/chromium/gpu/ipc/common/gpu_info_struct_traits.cc +++ b/chromium/gpu/ipc/common/gpu_info_struct_traits.cc @@ -20,46 +20,6 @@ bool StructTraits<gpu::mojom::GpuDeviceDataView, gpu::GPUInfo::GPUDevice>::Read( } // static -gpu::mojom::CollectInfoResult -EnumTraits<gpu::mojom::CollectInfoResult, gpu::CollectInfoResult>::ToMojom( - gpu::CollectInfoResult collect_info_result) { - switch (collect_info_result) { - case gpu::CollectInfoResult::kCollectInfoNone: - return gpu::mojom::CollectInfoResult::kCollectInfoNone; - case gpu::CollectInfoResult::kCollectInfoSuccess: - return gpu::mojom::CollectInfoResult::kCollectInfoSuccess; - case gpu::CollectInfoResult::kCollectInfoNonFatalFailure: - return gpu::mojom::CollectInfoResult::kCollectInfoNonFatalFailure; - case gpu::CollectInfoResult::kCollectInfoFatalFailure: - return gpu::mojom::CollectInfoResult::kCollectInfoFatalFailure; - } - NOTREACHED() << "Invalid CollectInfoResult value:" << collect_info_result; - return gpu::mojom::CollectInfoResult::kCollectInfoNone; -} - -// static -bool EnumTraits<gpu::mojom::CollectInfoResult, gpu::CollectInfoResult>:: - FromMojom(gpu::mojom::CollectInfoResult input, - gpu::CollectInfoResult* out) { - switch (input) { - case gpu::mojom::CollectInfoResult::kCollectInfoNone: - *out = gpu::CollectInfoResult::kCollectInfoNone; - return true; - case gpu::mojom::CollectInfoResult::kCollectInfoSuccess: - *out = gpu::CollectInfoResult::kCollectInfoSuccess; - return true; - case gpu::mojom::CollectInfoResult::kCollectInfoNonFatalFailure: - *out = gpu::CollectInfoResult::kCollectInfoNonFatalFailure; - return true; - case gpu::mojom::CollectInfoResult::kCollectInfoFatalFailure: - *out = gpu::CollectInfoResult::kCollectInfoFatalFailure; - return true; - } - NOTREACHED() << "Invalid CollectInfoResult value:" << input; - return false; -} - -// static gpu::mojom::VideoCodecProfile EnumTraits<gpu::mojom::VideoCodecProfile, gpu::VideoCodecProfile>::ToMojom( gpu::VideoCodecProfile video_codec_profile) { @@ -258,7 +218,6 @@ bool StructTraits<gpu::mojom::GpuInfoDataView, gpu::GPUInfo>::Read( out->supports_overlays = data.supports_overlays(); out->can_support_threaded_texture_mailbox = data.can_support_threaded_texture_mailbox(); - out->process_crash_count = data.process_crash_count(); out->jpeg_decode_accelerator_supported = data.jpeg_decode_accelerator_supported(); @@ -285,10 +244,7 @@ bool StructTraits<gpu::mojom::GpuInfoDataView, gpu::GPUInfo>::Read( data.ReadGlWsVendor(&out->gl_ws_vendor) && data.ReadGlWsVersion(&out->gl_ws_version) && data.ReadGlWsExtensions(&out->gl_ws_extensions) && - data.ReadBasicInfoState(&out->basic_info_state) && - data.ReadContextInfoState(&out->context_info_state) && #if defined(OS_WIN) - data.ReadDxDiagnosticsInfoState(&out->dx_diagnostics_info_state) && data.ReadDxDiagnostics(&out->dx_diagnostics) && #endif data.ReadVideoDecodeAcceleratorCapabilities( diff --git a/chromium/gpu/ipc/common/gpu_info_struct_traits.h b/chromium/gpu/ipc/common/gpu_info_struct_traits.h index e928acb18b8..28d52e983b1 100644 --- a/chromium/gpu/ipc/common/gpu_info_struct_traits.h +++ b/chromium/gpu/ipc/common/gpu_info_struct_traits.h @@ -43,15 +43,6 @@ struct StructTraits<gpu::mojom::GpuDeviceDataView, gpu::GPUInfo::GPUDevice> { }; template <> -struct EnumTraits<gpu::mojom::CollectInfoResult, gpu::CollectInfoResult> { - static gpu::mojom::CollectInfoResult ToMojom( - gpu::CollectInfoResult collect_info_result); - - static bool FromMojom(gpu::mojom::CollectInfoResult input, - gpu::CollectInfoResult* out); -}; - -template <> struct EnumTraits<gpu::mojom::VideoCodecProfile, gpu::VideoCodecProfile> { static gpu::mojom::VideoCodecProfile ToMojom( gpu::VideoCodecProfile video_codec_profile); @@ -228,10 +219,6 @@ struct StructTraits<gpu::mojom::GpuInfoDataView, gpu::GPUInfo> { static bool sandboxed(const gpu::GPUInfo& input) { return input.sandboxed; } - static int process_crash_count(const gpu::GPUInfo& input) { - return input.process_crash_count; - } - static bool in_process_gpu(const gpu::GPUInfo& input) { return input.in_process_gpu; } @@ -252,33 +239,11 @@ struct StructTraits<gpu::mojom::GpuInfoDataView, gpu::GPUInfo> { return input.can_support_threaded_texture_mailbox; } - static gpu::CollectInfoResult basic_info_state(const gpu::GPUInfo& input) { - return input.basic_info_state; - } - - static gpu::CollectInfoResult context_info_state(const gpu::GPUInfo& input) { - return input.context_info_state; - } #if defined(OS_WIN) static const gpu::DxDiagNode& dx_diagnostics(const gpu::GPUInfo& input) { return input.dx_diagnostics; } -#else - static const base::Optional<gpu::DxDiagNode>& dx_diagnostics( - const gpu::GPUInfo& input) { - static const base::Optional<gpu::DxDiagNode> dx_diag_node(base::nullopt); - return dx_diag_node; - } -#endif - - static gpu::CollectInfoResult dx_diagnostics_info_state( - const gpu::GPUInfo& input) { -#if defined(OS_WIN) - return input.dx_diagnostics_info_state; -#else - return gpu::CollectInfoResult::kCollectInfoNone; #endif - } static const gpu::VideoDecodeAcceleratorCapabilities& video_decode_accelerator_capabilities(const gpu::GPUInfo& input) { diff --git a/chromium/gpu/ipc/common/gpu_memory_buffer_support.cc b/chromium/gpu/ipc/common/gpu_memory_buffer_support.cc index 6d4a1ec5fe6..18bb4fd156b 100644 --- a/chromium/gpu/ipc/common/gpu_memory_buffer_support.cc +++ b/chromium/gpu/ipc/common/gpu_memory_buffer_support.cc @@ -40,22 +40,15 @@ bool IsNativeGpuMemoryBufferConfigurationSupported(gfx::BufferFormat format, switch (usage) { case gfx::BufferUsage::GPU_READ: case gfx::BufferUsage::SCANOUT: + case gfx::BufferUsage::SCANOUT_CPU_READ_WRITE: + case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE: + case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE_PERSISTENT: return format == gfx::BufferFormat::BGRA_8888 || format == gfx::BufferFormat::RGBA_8888 || format == gfx::BufferFormat::BGRX_8888 || format == gfx::BufferFormat::R_8 || format == gfx::BufferFormat::RGBA_F16 || - format == gfx::BufferFormat::UYVY_422 || - format == gfx::BufferFormat::YUV_420_BIPLANAR; - case gfx::BufferUsage::SCANOUT_CPU_READ_WRITE: - return format == gfx::BufferFormat::BGRA_8888 || - format == gfx::BufferFormat::RGBA_8888 || - format == gfx::BufferFormat::BGRX_8888; - case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE: - case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE_PERSISTENT: - return format == gfx::BufferFormat::R_8 || - format == gfx::BufferFormat::BGRA_8888 || - format == gfx::BufferFormat::RGBA_F16 || + format == gfx::BufferFormat::BGRX_1010102 || format == gfx::BufferFormat::UYVY_422 || format == gfx::BufferFormat::YUV_420_BIPLANAR; case gfx::BufferUsage::SCANOUT_VDA_WRITE: diff --git a/chromium/gpu/ipc/common/gpu_preferences.mojom b/chromium/gpu/ipc/common/gpu_preferences.mojom index 13fa84087eb..c0cd8762587 100644 --- a/chromium/gpu/ipc/common/gpu_preferences.mojom +++ b/chromium/gpu/ipc/common/gpu_preferences.mojom @@ -25,8 +25,6 @@ struct GpuPreferences { bool disable_gpu_watchdog; bool gpu_sandbox_start_early; - bool disable_web_rtc_hw_encoding; - // TODO(http://crbug.com/676224) Support preprocessing of mojoms. Following // variables should be used on Windows only. VpxDecodeVendors enable_accelerated_vpx_decode; diff --git a/chromium/gpu/ipc/common/gpu_preferences_struct_traits.h b/chromium/gpu/ipc/common/gpu_preferences_struct_traits.h index f9245b9bfb1..cc43de1a729 100644 --- a/chromium/gpu/ipc/common/gpu_preferences_struct_traits.h +++ b/chromium/gpu/ipc/common/gpu_preferences_struct_traits.h @@ -63,7 +63,6 @@ struct StructTraits<gpu::mojom::GpuPreferencesDataView, gpu::GpuPreferences> { out->gpu_startup_dialog = prefs.gpu_startup_dialog(); out->disable_gpu_watchdog = prefs.disable_gpu_watchdog(); out->gpu_sandbox_start_early = prefs.gpu_sandbox_start_early(); - out->disable_web_rtc_hw_encoding = prefs.disable_web_rtc_hw_encoding(); if (!prefs.ReadEnableAcceleratedVpxDecode( &out->enable_accelerated_vpx_decode)) return false; @@ -142,10 +141,6 @@ struct StructTraits<gpu::mojom::GpuPreferencesDataView, gpu::GpuPreferences> { return prefs.gpu_sandbox_start_early; } - static bool disable_web_rtc_hw_encoding(const gpu::GpuPreferences& prefs) { - return prefs.disable_web_rtc_hw_encoding; - } - static gpu::GpuPreferences::VpxDecodeVendors enable_accelerated_vpx_decode( const gpu::GpuPreferences& prefs) { return prefs.enable_accelerated_vpx_decode; diff --git a/chromium/gpu/ipc/common/gpu_preferences_util_unittest.cc b/chromium/gpu/ipc/common/gpu_preferences_util_unittest.cc index 89e6819b7b2..268d76b7d67 100644 --- a/chromium/gpu/ipc/common/gpu_preferences_util_unittest.cc +++ b/chromium/gpu/ipc/common/gpu_preferences_util_unittest.cc @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <algorithm> #include <cstring> #include "build/build_config.h" @@ -13,46 +14,79 @@ namespace gpu { namespace { -class ScopedGpuPreferences { - public: - ScopedGpuPreferences() { - // To make sure paddings are zeroed so we can use memcmp() in the tests. - memset(buffer_, 0, sizeof(buffer_)); - prefs_ = new (buffer_) GpuPreferences(); - } - - ~ScopedGpuPreferences() { prefs_->~GpuPreferences(); } - - GpuPreferences& Ref() { return *prefs_; } - - private: - GpuPreferences* prefs_; - alignas(GpuPreferences) char buffer_[sizeof(GpuPreferences)]; -}; +void CheckGpuPreferencesEqual(GpuPreferences left, GpuPreferences right) { + EXPECT_EQ(left.single_process, right.single_process); + EXPECT_EQ(left.in_process_gpu, right.in_process_gpu); + EXPECT_EQ(left.disable_accelerated_video_decode, + right.disable_accelerated_video_decode); + EXPECT_EQ(left.disable_accelerated_video_encode, + right.disable_accelerated_video_encode); + EXPECT_EQ(left.gpu_startup_dialog, right.gpu_startup_dialog); + EXPECT_EQ(left.disable_gpu_watchdog, right.disable_gpu_watchdog); + EXPECT_EQ(left.gpu_sandbox_start_early, right.gpu_sandbox_start_early); + EXPECT_EQ(left.enable_accelerated_vpx_decode, + right.enable_accelerated_vpx_decode); + EXPECT_EQ(left.enable_low_latency_dxva, right.enable_low_latency_dxva); + EXPECT_EQ(left.enable_zero_copy_dxgi_video, + right.enable_zero_copy_dxgi_video); + EXPECT_EQ(left.enable_nv12_dxgi_video, right.enable_nv12_dxgi_video); + EXPECT_EQ(left.enable_media_foundation_vea_on_windows7, + right.enable_media_foundation_vea_on_windows7); + EXPECT_EQ(left.disable_software_rasterizer, + right.disable_software_rasterizer); + EXPECT_EQ(left.log_gpu_control_list_decisions, + right.log_gpu_control_list_decisions); + EXPECT_EQ(left.compile_shader_always_succeeds, + right.compile_shader_always_succeeds); + EXPECT_EQ(left.disable_gl_error_limit, right.disable_gl_error_limit); + EXPECT_EQ(left.disable_glsl_translator, right.disable_glsl_translator); + EXPECT_EQ(left.disable_shader_name_hashing, + right.disable_shader_name_hashing); + EXPECT_EQ(left.enable_gpu_command_logging, right.enable_gpu_command_logging); + EXPECT_EQ(left.enable_gpu_debugging, right.enable_gpu_debugging); + EXPECT_EQ(left.enable_gpu_service_logging_gpu, + right.enable_gpu_service_logging_gpu); + EXPECT_EQ(left.enable_gpu_driver_debug_logging, + right.enable_gpu_driver_debug_logging); + EXPECT_EQ(left.disable_gpu_program_cache, right.disable_gpu_program_cache); + EXPECT_EQ(left.enforce_gl_minimums, right.enforce_gl_minimums); + EXPECT_EQ(left.force_gpu_mem_available, right.force_gpu_mem_available); + EXPECT_EQ(left.gpu_program_cache_size, right.gpu_program_cache_size); + EXPECT_EQ(left.disable_gpu_shader_disk_cache, + right.disable_gpu_shader_disk_cache); + EXPECT_EQ(left.enable_threaded_texture_mailboxes, + right.enable_threaded_texture_mailboxes); + EXPECT_EQ(left.gl_shader_interm_output, right.gl_shader_interm_output); + EXPECT_EQ(left.emulate_shader_precision, right.emulate_shader_precision); + EXPECT_EQ(left.enable_raster_decoder, right.enable_raster_decoder); + EXPECT_EQ(left.enable_gpu_service_logging, right.enable_gpu_service_logging); + EXPECT_EQ(left.enable_gpu_service_tracing, right.enable_gpu_service_tracing); + EXPECT_EQ(left.use_passthrough_cmd_decoder, + right.use_passthrough_cmd_decoder); + EXPECT_EQ(left.disable_biplanar_gpu_memory_buffers_for_video_frames, + right.disable_biplanar_gpu_memory_buffers_for_video_frames); + EXPECT_EQ(left.texture_target_exception_list, + right.texture_target_exception_list); + EXPECT_EQ(left.disable_gpu_driver_bug_workarounds, + right.disable_gpu_driver_bug_workarounds); + EXPECT_EQ(left.ignore_gpu_blacklist, right.ignore_gpu_blacklist); +} } // namespace -// TODO(https://crbug.com/799458): Fix this test. -#if defined(OS_WIN) -#define MAYBE_EncodeDecode DISABLED_EncodeDecode -#else -#define MAYBE_EncodeDecode EncodeDecode -#endif -TEST(GpuPreferencesUtilTest, MAYBE_EncodeDecode) { +TEST(GpuPreferencesUtilTest, EncodeDecode) { { // Testing default values. - ScopedGpuPreferences scoped_input_prefs, scoped_decoded_prefs; - GpuPreferences& input_prefs = scoped_input_prefs.Ref(); - GpuPreferences& decoded_prefs = scoped_decoded_prefs.Ref(); + GpuPreferences input_prefs; + GpuPreferences decoded_prefs; std::string encoded = GpuPreferencesToSwitchValue(input_prefs); bool flag = SwitchValueToGpuPreferences(encoded, &decoded_prefs); EXPECT_TRUE(flag); - EXPECT_EQ(0, memcmp(&input_prefs, &decoded_prefs, sizeof(input_prefs))); + CheckGpuPreferencesEqual(input_prefs, decoded_prefs); } { // Change all fields to non default values. - ScopedGpuPreferences scoped_input_prefs, scoped_decoded_prefs; - GpuPreferences& input_prefs = scoped_input_prefs.Ref(); - GpuPreferences& decoded_prefs = scoped_decoded_prefs.Ref(); + GpuPreferences input_prefs; + GpuPreferences decoded_prefs; GpuPreferences default_prefs; mojom::GpuPreferences prefs_mojom; @@ -76,7 +110,6 @@ TEST(GpuPreferencesUtilTest, MAYBE_EncodeDecode) { GPU_PREFERENCES_FIELD(gpu_startup_dialog, true) GPU_PREFERENCES_FIELD(disable_gpu_watchdog, true) GPU_PREFERENCES_FIELD(gpu_sandbox_start_early, true) - GPU_PREFERENCES_FIELD(disable_web_rtc_hw_encoding, true) GPU_PREFERENCES_FIELD(enable_accelerated_vpx_decode, GpuPreferences::VPX_VENDOR_AMD) GPU_PREFERENCES_FIELD(enable_low_latency_dxva, false) @@ -102,6 +135,7 @@ TEST(GpuPreferencesUtilTest, MAYBE_EncodeDecode) { GPU_PREFERENCES_FIELD(enable_threaded_texture_mailboxes, true) GPU_PREFERENCES_FIELD(gl_shader_interm_output, true) GPU_PREFERENCES_FIELD(emulate_shader_precision, true) + GPU_PREFERENCES_FIELD(enable_raster_decoder, true) GPU_PREFERENCES_FIELD(enable_gpu_service_logging, true) GPU_PREFERENCES_FIELD(enable_gpu_service_tracing, true) GPU_PREFERENCES_FIELD(use_passthrough_cmd_decoder, true) @@ -110,11 +144,16 @@ TEST(GpuPreferencesUtilTest, MAYBE_EncodeDecode) { GPU_PREFERENCES_FIELD(disable_gpu_driver_bug_workarounds, true) GPU_PREFERENCES_FIELD(ignore_gpu_blacklist, true) + input_prefs.texture_target_exception_list.emplace_back( + gfx::BufferUsage::SCANOUT, gfx::BufferFormat::RGBA_8888); + input_prefs.texture_target_exception_list.emplace_back( + gfx::BufferUsage::GPU_READ, gfx::BufferFormat::BGRA_8888); + // Make sure every field is encoded/decoded. std::string encoded = GpuPreferencesToSwitchValue(input_prefs); bool flag = SwitchValueToGpuPreferences(encoded, &decoded_prefs); EXPECT_TRUE(flag); - EXPECT_EQ(0, memcmp(&input_prefs, &decoded_prefs, sizeof(input_prefs))); + CheckGpuPreferencesEqual(input_prefs, decoded_prefs); } } diff --git a/chromium/gpu/ipc/common/struct_traits_unittest.cc b/chromium/gpu/ipc/common/struct_traits_unittest.cc index ddf0a7944a4..7c30aebb965 100644 --- a/chromium/gpu/ipc/common/struct_traits_unittest.cc +++ b/chromium/gpu/ipc/common/struct_traits_unittest.cc @@ -150,18 +150,11 @@ TEST_F(StructTraitsTest, GpuInfo) { const bool software_rendering = true; const bool direct_rendering = true; const bool sandboxed = true; - const int process_crash_count = 0xdead; const bool in_process_gpu = true; const bool passthrough_cmd_decoder = true; const bool direct_composition = true; const bool supports_overlays = true; - const gpu::CollectInfoResult basic_info_state = - gpu::CollectInfoResult::kCollectInfoSuccess; - const gpu::CollectInfoResult context_info_state = - gpu::CollectInfoResult::kCollectInfoSuccess; #if defined(OS_WIN) - const gpu::CollectInfoResult dx_diagnostics_info_state = - gpu::CollectInfoResult::kCollectInfoSuccess; const DxDiagNode dx_diagnostics; #endif const gpu::VideoDecodeAcceleratorCapabilities @@ -199,15 +192,11 @@ TEST_F(StructTraitsTest, GpuInfo) { input.software_rendering = software_rendering; input.direct_rendering = direct_rendering; input.sandboxed = sandboxed; - input.process_crash_count = process_crash_count; input.in_process_gpu = in_process_gpu; input.passthrough_cmd_decoder = passthrough_cmd_decoder; input.direct_composition = direct_composition; input.supports_overlays = supports_overlays; - input.basic_info_state = basic_info_state; - input.context_info_state = context_info_state; #if defined(OS_WIN) - input.dx_diagnostics_info_state = dx_diagnostics_info_state; input.dx_diagnostics = dx_diagnostics; #endif input.video_decode_accelerator_capabilities = @@ -261,15 +250,11 @@ TEST_F(StructTraitsTest, GpuInfo) { EXPECT_EQ(software_rendering, output.software_rendering); EXPECT_EQ(direct_rendering, output.direct_rendering); EXPECT_EQ(sandboxed, output.sandboxed); - EXPECT_EQ(process_crash_count, output.process_crash_count); EXPECT_EQ(in_process_gpu, output.in_process_gpu); EXPECT_EQ(passthrough_cmd_decoder, output.passthrough_cmd_decoder); EXPECT_EQ(direct_composition, output.direct_composition); EXPECT_EQ(supports_overlays, output.supports_overlays); - EXPECT_EQ(basic_info_state, output.basic_info_state); - EXPECT_EQ(context_info_state, output.context_info_state); #if defined(OS_WIN) - EXPECT_EQ(output.dx_diagnostics_info_state, dx_diagnostics_info_state); EXPECT_EQ(dx_diagnostics.values, output.dx_diagnostics.values); #endif EXPECT_EQ(output.video_decode_accelerator_capabilities.flags, diff --git a/chromium/gpu/ipc/gpu_in_process_thread_service.cc b/chromium/gpu/ipc/gpu_in_process_thread_service.cc index 7115c15302d..4fc78253abc 100644 --- a/chromium/gpu/ipc/gpu_in_process_thread_service.cc +++ b/chromium/gpu/ipc/gpu_in_process_thread_service.cc @@ -10,28 +10,31 @@ namespace gpu { GpuInProcessThreadService::GpuInProcessThreadService( + bool use_virtualized_gl_context, scoped_refptr<base::SingleThreadTaskRunner> task_runner, gpu::SyncPointManager* sync_point_manager, gpu::MailboxManager* mailbox_manager, scoped_refptr<gl::GLShareGroup> share_group, - const GpuFeatureInfo& gpu_feature_info) - : gpu::InProcessCommandBuffer::Service(GpuPreferences(), + const GpuFeatureInfo& gpu_feature_info, + const GpuPreferences& gpu_preferences) + : gpu::InProcessCommandBuffer::Service(gpu_preferences, mailbox_manager, share_group, gpu_feature_info), + use_virtualized_gl_context_(use_virtualized_gl_context), task_runner_(task_runner), sync_point_manager_(sync_point_manager) {} -void GpuInProcessThreadService::ScheduleTask(const base::Closure& task) { - task_runner_->PostTask(FROM_HERE, task); +void GpuInProcessThreadService::ScheduleTask(base::OnceClosure task) { + task_runner_->PostTask(FROM_HERE, std::move(task)); } -void GpuInProcessThreadService::ScheduleDelayedWork(const base::Closure& task) { - task_runner_->PostDelayedTask(FROM_HERE, task, +void GpuInProcessThreadService::ScheduleDelayedWork(base::OnceClosure task) { + task_runner_->PostDelayedTask(FROM_HERE, std::move(task), base::TimeDelta::FromMilliseconds(2)); } bool GpuInProcessThreadService::UseVirtualizedGLContexts() { - return true; + return use_virtualized_gl_context_; } gpu::SyncPointManager* GpuInProcessThreadService::sync_point_manager() { diff --git a/chromium/gpu/ipc/gpu_in_process_thread_service.h b/chromium/gpu/ipc/gpu_in_process_thread_service.h index a9bcece67c3..714d9745ab2 100644 --- a/chromium/gpu/ipc/gpu_in_process_thread_service.h +++ b/chromium/gpu/ipc/gpu_in_process_thread_service.h @@ -21,15 +21,17 @@ class GL_IN_PROCESS_CONTEXT_EXPORT GpuInProcessThreadService public base::RefCountedThreadSafe<GpuInProcessThreadService> { public: GpuInProcessThreadService( + bool use_virtualized_gl_context, scoped_refptr<base::SingleThreadTaskRunner> task_runner, gpu::SyncPointManager* sync_point_manager, gpu::MailboxManager* mailbox_manager, scoped_refptr<gl::GLShareGroup> share_group, - const GpuFeatureInfo& gpu_feature_info); + const GpuFeatureInfo& gpu_feature_info, + const GpuPreferences& gpu_preferences); // gpu::InProcessCommandBuffer::Service implementation. - void ScheduleTask(const base::Closure& task) override; - void ScheduleDelayedWork(const base::Closure& task) override; + void ScheduleTask(base::OnceClosure task) override; + void ScheduleDelayedWork(base::OnceClosure task) override; bool UseVirtualizedGLContexts() override; gpu::SyncPointManager* sync_point_manager() override; void AddRef() const override; @@ -41,6 +43,8 @@ class GL_IN_PROCESS_CONTEXT_EXPORT GpuInProcessThreadService ~GpuInProcessThreadService() override; + const bool use_virtualized_gl_context_; + scoped_refptr<base::SingleThreadTaskRunner> task_runner_; gpu::SyncPointManager* sync_point_manager_; // Non-owning. diff --git a/chromium/gpu/ipc/host/gpu_memory_buffer_support.cc b/chromium/gpu/ipc/host/gpu_memory_buffer_support.cc index 78c7c82c458..e0c5420dc7e 100644 --- a/chromium/gpu/ipc/host/gpu_memory_buffer_support.cc +++ b/chromium/gpu/ipc/host/gpu_memory_buffer_support.cc @@ -40,15 +40,24 @@ GpuMemoryBufferConfigurationSet GetNativeGpuMemoryBufferConfigurations() { defined(OS_ANDROID) if (AreNativeGpuMemoryBuffersEnabled()) { const gfx::BufferFormat kNativeFormats[] = { - gfx::BufferFormat::R_8, gfx::BufferFormat::RG_88, - gfx::BufferFormat::R_16, gfx::BufferFormat::BGR_565, - gfx::BufferFormat::RGBA_4444, gfx::BufferFormat::RGBA_8888, - gfx::BufferFormat::BGRA_8888, gfx::BufferFormat::BGRX_1010102, - gfx::BufferFormat::RGBA_F16, gfx::BufferFormat::UYVY_422, - gfx::BufferFormat::YVU_420, gfx::BufferFormat::YUV_420_BIPLANAR}; + gfx::BufferFormat::R_8, + gfx::BufferFormat::RG_88, + gfx::BufferFormat::R_16, + gfx::BufferFormat::BGR_565, + gfx::BufferFormat::RGBA_4444, + gfx::BufferFormat::RGBA_8888, + gfx::BufferFormat::BGRA_8888, + gfx::BufferFormat::BGRX_1010102, + gfx::BufferFormat::RGBX_1010102, + gfx::BufferFormat::RGBA_F16, + gfx::BufferFormat::UYVY_422, + gfx::BufferFormat::YVU_420, + gfx::BufferFormat::YUV_420_BIPLANAR}; const gfx::BufferUsage kNativeUsages[] = { - gfx::BufferUsage::GPU_READ, gfx::BufferUsage::SCANOUT, + gfx::BufferUsage::GPU_READ, + gfx::BufferUsage::SCANOUT, gfx::BufferUsage::SCANOUT_CAMERA_READ_WRITE, + gfx::BufferUsage::SCANOUT_CPU_READ_WRITE, gfx::BufferUsage::GPU_READ_CPU_READ_WRITE, gfx::BufferUsage::GPU_READ_CPU_READ_WRITE_PERSISTENT}; for (auto format : kNativeFormats) { diff --git a/chromium/gpu/ipc/in_process_command_buffer.cc b/chromium/gpu/ipc/in_process_command_buffer.cc index 229618261e2..b19f9a4fe8e 100644 --- a/chromium/gpu/ipc/in_process_command_buffer.cc +++ b/chromium/gpu/ipc/in_process_command_buffer.cc @@ -13,6 +13,7 @@ #include "base/atomic_sequence_num.h" #include "base/bind.h" #include "base/bind_helpers.h" +#include "base/callback_helpers.h" #include "base/command_line.h" #include "base/containers/queue.h" #include "base/lazy_instance.h" @@ -72,11 +73,15 @@ base::AtomicSequenceNumber g_next_command_buffer_id; base::AtomicSequenceNumber g_next_image_id; template <typename T> -static void RunTaskWithResult(base::Callback<T(void)> task, - T* result, - base::WaitableEvent* completion) { - *result = task.Run(); - completion->Signal(); +base::OnceClosure WrapTaskWithResult(base::OnceCallback<T(void)> task, + T* result, + base::WaitableEvent* completion) { + auto wrapper = [](base::OnceCallback<T(void)> task, T* result, + base::WaitableEvent* completion) { + *result = std::move(task).Run(); + completion->Signal(); + }; + return base::BindOnce(wrapper, std::move(task), result, completion); } class GpuInProcessThreadHolder : public base::Thread { @@ -95,9 +100,10 @@ class GpuInProcessThreadHolder : public base::Thread { const scoped_refptr<InProcessCommandBuffer::Service>& GetGpuThreadService() { if (!gpu_thread_service_) { - gpu_thread_service_ = new GpuInProcessThreadService( - task_runner(), sync_point_manager_.get(), nullptr, nullptr, - gpu_feature_info_); + gpu_thread_service_ = base::MakeRefCounted<GpuInProcessThreadService>( + true /* use_virtualized_gl_context */, task_runner(), + sync_point_manager_.get(), nullptr, nullptr, gpu_feature_info_, + GpuPreferences()); } return gpu_thread_service_; } @@ -137,6 +143,8 @@ scoped_refptr<InProcessCommandBuffer::Service> GetInitialService( } // anonyous namespace +const int InProcessCommandBuffer::kGpuMemoryBufferClientId = 1; + InProcessCommandBuffer::Service::Service( const GpuPreferences& gpu_preferences, MailboxManager* mailbox_manager, @@ -270,16 +278,16 @@ gpu::ContextResult InProcessCommandBuffer::Initialize( InitializeOnGpuThreadParams params(is_offscreen, window, attribs, &capabilities, share_group, image_factory); - base::Callback<gpu::ContextResult(void)> init_task = - base::Bind(&InProcessCommandBuffer::InitializeOnGpuThread, - base::Unretained(this), params); + base::OnceCallback<gpu::ContextResult(void)> init_task = + base::BindOnce(&InProcessCommandBuffer::InitializeOnGpuThread, + base::Unretained(this), params); base::WaitableEvent completion( base::WaitableEvent::ResetPolicy::MANUAL, base::WaitableEvent::InitialState::NOT_SIGNALED); gpu::ContextResult result = gpu::ContextResult::kSuccess; - QueueTask(true, base::Bind(&RunTaskWithResult<gpu::ContextResult>, init_task, - &result, &completion)); + QueueOnceTask(true, + WrapTaskWithResult(std::move(init_task), &result, &completion)); completion.Wait(); if (result == gpu::ContextResult::kSuccess) @@ -314,7 +322,7 @@ gpu::ContextResult InProcessCommandBuffer::InitializeOnGpuThread( service_->framebuffer_completeness_cache(), feature_info, bind_generates_resource, service_->image_manager(), nullptr /* image_factory */, nullptr /* progress_reporter */, - GpuFeatureInfo(), service_->discardable_manager()); + service_->gpu_feature_info(), service_->discardable_manager()); command_buffer_ = std::make_unique<CommandBufferService>( this, transfer_buffer_manager_.get()); @@ -352,6 +360,8 @@ gpu::ContextResult InProcessCommandBuffer::InitializeOnGpuThread( GetNamespaceID(), GetCommandBufferID(), sync_point_order_data_->sequence_id()); + // TODO(crbug.com/811979): Unify logic for using virtualized contexts in + // InProcessCommandBuffer and GLES2CommandBufferStub. use_virtualized_gl_context_ = service_->UseVirtualizedGLContexts() || decoder_->GetContextGroup() ->feature_info() @@ -440,10 +450,10 @@ void InProcessCommandBuffer::Destroy() { base::WaitableEvent::ResetPolicy::MANUAL, base::WaitableEvent::InitialState::NOT_SIGNALED); bool result = false; - base::Callback<bool(void)> destroy_task = base::Bind( + base::OnceCallback<bool(void)> destroy_task = base::BindOnce( &InProcessCommandBuffer::DestroyOnGpuThread, base::Unretained(this)); - QueueTask(true, base::Bind(&RunTaskWithResult<bool>, destroy_task, &result, - &completion)); + QueueOnceTask( + true, WrapTaskWithResult(std::move(destroy_task), &result, &completion)); completion.Wait(); } @@ -460,8 +470,14 @@ bool InProcessCommandBuffer::DestroyOnGpuThread() { decoder_.reset(); } command_buffer_.reset(); - context_ = nullptr; + + // Destroy the surface with the context current, some surface destructors make + // GL calls. + if (context_) + context_->MakeCurrent(surface_.get()); surface_ = nullptr; + + context_ = nullptr; if (sync_point_order_data_) { sync_point_order_data_->Destroy(); sync_point_order_data_ = nullptr; @@ -510,10 +526,10 @@ void InProcessCommandBuffer::OnContextLost() { gpu_control_client_->OnGpuControlLostContext(); } -void InProcessCommandBuffer::QueueTask(bool out_of_order, - const base::Closure& task) { +void InProcessCommandBuffer::QueueOnceTask(bool out_of_order, + base::OnceClosure task) { if (out_of_order) { - service_->ScheduleTask(task); + service_->ScheduleTask(std::move(task)); return; } // Release the |task_queue_lock_| before calling ScheduleTask because @@ -521,7 +537,23 @@ void InProcessCommandBuffer::QueueTask(bool out_of_order, uint32_t order_num = sync_point_order_data_->GenerateUnprocessedOrderNumber(); { base::AutoLock lock(task_queue_lock_); - task_queue_.push(std::make_unique<GpuTask>(task, order_num)); + std::unique_ptr<GpuTask> gpu_task = + std::make_unique<GpuTask>(std::move(task), order_num); + task_queue_.push(std::move(gpu_task)); + } + service_->ScheduleTask(base::BindOnce( + &InProcessCommandBuffer::ProcessTasksOnGpuThread, gpu_thread_weak_ptr_)); +} + +void InProcessCommandBuffer::QueueRepeatableTask(base::RepeatingClosure task) { + // Release the |task_queue_lock_| before calling ScheduleTask because + // the callback may get called immediately and attempt to acquire the lock. + uint32_t order_num = sync_point_order_data_->GenerateUnprocessedOrderNumber(); + { + base::AutoLock lock(task_queue_lock_); + std::unique_ptr<GpuTask> gpu_task = + std::make_unique<GpuTask>(std::move(task), order_num); + task_queue_.push(std::move(gpu_task)); } service_->ScheduleTask(base::Bind( &InProcessCommandBuffer::ProcessTasksOnGpuThread, gpu_thread_weak_ptr_)); @@ -536,16 +568,17 @@ void InProcessCommandBuffer::ProcessTasksOnGpuThread() { if (task_queue_.empty()) break; GpuTask* task = task_queue_.front().get(); - sync_point_order_data_->BeginProcessingOrderNumber(task->order_number); - task->callback.Run(); + sync_point_order_data_->BeginProcessingOrderNumber(task->order_number()); + task->Run(); if (!command_buffer_->scheduled() && !service_->BlockThreadOnWaitSyncToken()) { - sync_point_order_data_->PauseProcessingOrderNumber(task->order_number); + sync_point_order_data_->PauseProcessingOrderNumber(task->order_number()); // Don't pop the task if it was preempted - it may have been preempted, so // we need to execute it again later. + DCHECK(task->is_repeatable()); return; } - sync_point_order_data_->FinishProcessingOrderNumber(task->order_number); + sync_point_order_data_->FinishProcessingOrderNumber(task->order_number()); task_queue_.pop(); } } @@ -625,11 +658,11 @@ void InProcessCommandBuffer::Flush(int32_t put_offset) { return; last_put_offset_ = put_offset; - base::Closure task = - base::Bind(&InProcessCommandBuffer::FlushOnGpuThread, - gpu_thread_weak_ptr_, put_offset, snapshot_requested_); + base::RepeatingClosure task = base::BindRepeating( + &InProcessCommandBuffer::FlushOnGpuThread, gpu_thread_weak_ptr_, + put_offset, snapshot_requested_); snapshot_requested_ = false; - QueueTask(false, task); + QueueRepeatableTask(std::move(task)); flushed_fence_sync_release_ = next_fence_sync_release_ - 1; } @@ -673,10 +706,10 @@ void InProcessCommandBuffer::SetGetBuffer(int32_t shm_id) { base::WaitableEvent completion( base::WaitableEvent::ResetPolicy::MANUAL, base::WaitableEvent::InitialState::NOT_SIGNALED); - base::Closure task = - base::Bind(&InProcessCommandBuffer::SetGetBufferOnGpuThread, - base::Unretained(this), shm_id, &completion); - QueueTask(false, task); + base::OnceClosure task = + base::BindOnce(&InProcessCommandBuffer::SetGetBufferOnGpuThread, + base::Unretained(this), shm_id, &completion); + QueueOnceTask(false, std::move(task)); completion.Wait(); last_put_offset_ = 0; @@ -701,11 +734,11 @@ scoped_refptr<Buffer> InProcessCommandBuffer::CreateTransferBuffer( void InProcessCommandBuffer::DestroyTransferBuffer(int32_t id) { CheckSequencedThread(); - base::Closure task = - base::Bind(&InProcessCommandBuffer::DestroyTransferBufferOnGpuThread, - base::Unretained(this), id); + base::OnceClosure task = + base::BindOnce(&InProcessCommandBuffer::DestroyTransferBufferOnGpuThread, + base::Unretained(this), id); - QueueTask(false, task); + QueueOnceTask(false, std::move(task)); } void InProcessCommandBuffer::DestroyTransferBufferOnGpuThread(int32_t id) { @@ -758,13 +791,14 @@ int32_t InProcessCommandBuffer::CreateImage(ClientBuffer buffer, DCHECK_EQ(fence_sync - 1, flushed_fence_sync_release_); } - QueueTask(false, base::Bind(&InProcessCommandBuffer::CreateImageOnGpuThread, - base::Unretained(this), new_id, handle, - gfx::Size(base::checked_cast<int>(width), - base::checked_cast<int>(height)), - gpu_memory_buffer->GetFormat(), - base::checked_cast<uint32_t>(internalformat), - fence_sync)); + QueueOnceTask( + false, + base::BindOnce(&InProcessCommandBuffer::CreateImageOnGpuThread, + base::Unretained(this), new_id, handle, + gfx::Size(base::checked_cast<int>(width), + base::checked_cast<int>(height)), + gpu_memory_buffer->GetFormat(), + base::checked_cast<uint32_t>(internalformat), fence_sync)); if (fence_sync) { flushed_fence_sync_release_ = fence_sync; @@ -814,12 +848,9 @@ void InProcessCommandBuffer::CreateImageOnGpuThread( return; } - // Note: this assumes that client ID is always 0. - const int kClientId = 0; - scoped_refptr<gl::GLImage> image = image_factory_->CreateImageForGpuMemoryBuffer( - handle, size, format, internalformat, kClientId, + handle, size, format, internalformat, kGpuMemoryBufferClientId, kNullSurfaceHandle); if (!image.get()) { LOG(ERROR) << "Failed to create image for buffer."; @@ -838,8 +869,9 @@ void InProcessCommandBuffer::CreateImageOnGpuThread( void InProcessCommandBuffer::DestroyImage(int32_t id) { CheckSequencedThread(); - QueueTask(false, base::Bind(&InProcessCommandBuffer::DestroyImageOnGpuThread, - base::Unretained(this), id)); + QueueOnceTask(false, + base::BindOnce(&InProcessCommandBuffer::DestroyImageOnGpuThread, + base::Unretained(this), id)); } void InProcessCommandBuffer::DestroyImageOnGpuThread(int32_t id) { @@ -940,30 +972,37 @@ void InProcessCommandBuffer::OnRescheduleAfterFinished() { void InProcessCommandBuffer::SignalSyncTokenOnGpuThread( const SyncToken& sync_token, - const base::Closure& callback) { - if (!sync_point_client_state_->Wait(sync_token, WrapCallback(callback))) - callback.Run(); + base::OnceClosure callback) { + base::RepeatingClosure maybe_pass_callback = + base::AdaptCallbackForRepeating(WrapCallback(std::move(callback))); + if (!sync_point_client_state_->Wait(sync_token, maybe_pass_callback)) { + maybe_pass_callback.Run(); + } } void InProcessCommandBuffer::SignalQuery(unsigned query_id, - const base::Closure& callback) { + base::OnceClosure callback) { CheckSequencedThread(); - QueueTask(false, base::Bind(&InProcessCommandBuffer::SignalQueryOnGpuThread, - base::Unretained(this), query_id, - WrapCallback(callback))); + QueueOnceTask(false, + base::BindOnce(&InProcessCommandBuffer::SignalQueryOnGpuThread, + base::Unretained(this), query_id, + WrapCallback(std::move(callback)))); } void InProcessCommandBuffer::SignalQueryOnGpuThread( unsigned query_id, - const base::Closure& callback) { - gles2::QueryManager* query_manager_ = decoder_->GetQueryManager(); - DCHECK(query_manager_); + base::OnceClosure callback) { + gles2::QueryManager* query_manager = decoder_->GetQueryManager(); + if (query_manager) { + gles2::QueryManager::Query* query = query_manager->GetQuery(query_id); + if (query) { + query->AddCallback(base::AdaptCallbackForRepeating(std::move(callback))); + return; + } + } - gles2::QueryManager::Query* query = query_manager_->GetQuery(query_id); - if (!query) - callback.Run(); - else - query->AddCallback(callback); + // Something went wrong, run callback immediately. + std::move(callback).Run(); } void InProcessCommandBuffer::CreateGpuFence(uint32_t gpu_fence_id, @@ -976,11 +1015,9 @@ void InProcessCommandBuffer::CreateGpuFence(uint32_t gpu_fence_id, gfx::GpuFenceHandle handle = gfx::CloneHandleForIPC(gpu_fence->GetGpuFenceHandle()); - // TODO(crbug.com/789349): Should be base::BindOnce, but QueueTask requires a - // RepeatingClosure. - QueueTask(false, base::BindRepeating( - &InProcessCommandBuffer::CreateGpuFenceOnGpuThread, - base::Unretained(this), gpu_fence_id, handle)); + QueueOnceTask( + false, base::BindOnce(&InProcessCommandBuffer::CreateGpuFenceOnGpuThread, + base::Unretained(this), gpu_fence_id, handle)); } void InProcessCommandBuffer::CreateGpuFenceOnGpuThread( @@ -1007,17 +1044,13 @@ void InProcessCommandBuffer::GetGpuFence( uint32_t gpu_fence_id, base::OnceCallback<void(std::unique_ptr<gfx::GpuFence>)> callback) { CheckSequencedThread(); - // TODO(crbug.com/789349): QueueTask requires a RepeatingClosure, - // but it's actually single use, hence AdaptCallbackForRepeating. - // Cf. WrapCallback, which we can't use directly since our callback - // still needs an argument, so it's not a Closure. auto task_runner = base::ThreadTaskRunnerHandle::IsSet() ? base::ThreadTaskRunnerHandle::Get() : nullptr; - QueueTask(false, base::AdaptCallbackForRepeating(base::BindOnce( - &InProcessCommandBuffer::GetGpuFenceOnGpuThread, - base::Unretained(this), gpu_fence_id, task_runner, - std::move(callback)))); + QueueOnceTask( + false, base::BindOnce(&InProcessCommandBuffer::GetGpuFenceOnGpuThread, + base::Unretained(this), gpu_fence_id, task_runner, + std::move(callback))); } void InProcessCommandBuffer::GetGpuFenceOnGpuThread( @@ -1084,12 +1117,12 @@ bool InProcessCommandBuffer::IsFenceSyncReleased(uint64_t release) { } void InProcessCommandBuffer::SignalSyncToken(const SyncToken& sync_token, - const base::Closure& callback) { + base::OnceClosure callback) { CheckSequencedThread(); - QueueTask( - false, - base::Bind(&InProcessCommandBuffer::SignalSyncTokenOnGpuThread, - base::Unretained(this), sync_token, WrapCallback(callback))); + QueueOnceTask( + false, base::BindOnce(&InProcessCommandBuffer::SignalSyncTokenOnGpuThread, + base::Unretained(this), sync_token, + WrapCallback(std::move(callback)))); } void InProcessCommandBuffer::WaitSyncTokenHint(const SyncToken& sync_token) {} @@ -1110,6 +1143,9 @@ void InProcessCommandBuffer::DidCreateAcceleratedSurfaceChildWindow( // In the browser process call ::SetParent() directly. if (!gpu_channel_manager_delegate_) { ::SetParent(child_window, parent_window); + // Move D3D window behind Chrome's window to avoid losing some messages. + ::SetWindowPos(child_window, HWND_BOTTOM, 0, 0, 0, 0, + SWP_NOMOVE | SWP_NOSIZE); return; } @@ -1223,42 +1259,55 @@ namespace { void PostCallback( const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, - const base::Closure& callback) { + base::OnceClosure callback) { // The task_runner.get() check is to support using InProcessCommandBuffer on // a thread without a message loop. if (task_runner.get() && !task_runner->BelongsToCurrentThread()) { - task_runner->PostTask(FROM_HERE, callback); + task_runner->PostTask(FROM_HERE, std::move(callback)); } else { - callback.Run(); + std::move(callback).Run(); } } -void RunOnTargetThread(std::unique_ptr<base::Closure> callback) { - DCHECK(callback.get()); - callback->Run(); +void RunOnTargetThread(base::OnceClosure callback) { + DCHECK(!callback.is_null()); + std::move(callback).Run(); } } // anonymous namespace -base::Closure InProcessCommandBuffer::WrapCallback( - const base::Closure& callback) { +base::OnceClosure InProcessCommandBuffer::WrapCallback( + base::OnceClosure callback) { // Make sure the callback gets deleted on the target thread by passing // ownership. - std::unique_ptr<base::Closure> scoped_callback(new base::Closure(callback)); - base::Closure callback_on_client_thread = - base::Bind(&RunOnTargetThread, base::Passed(&scoped_callback)); - base::Closure wrapped_callback = - base::Bind(&PostCallback, base::ThreadTaskRunnerHandle::IsSet() - ? base::ThreadTaskRunnerHandle::Get() - : nullptr, - callback_on_client_thread); + base::OnceClosure callback_on_client_thread = + base::BindOnce(&RunOnTargetThread, std::move(callback)); + base::OnceClosure wrapped_callback = + base::BindOnce(&PostCallback, + base::ThreadTaskRunnerHandle::IsSet() + ? base::ThreadTaskRunnerHandle::Get() + : nullptr, + std::move(callback_on_client_thread)); return wrapped_callback; } -InProcessCommandBuffer::GpuTask::GpuTask(const base::Closure& callback, +InProcessCommandBuffer::GpuTask::GpuTask(base::OnceClosure callback, + uint32_t order_number) + : once_closure_(std::move(callback)), order_number_(order_number) {} + +InProcessCommandBuffer::GpuTask::GpuTask(base::RepeatingClosure callback, uint32_t order_number) - : callback(callback), order_number(order_number) {} + : repeating_closure_(std::move(callback)), order_number_(order_number) {} InProcessCommandBuffer::GpuTask::~GpuTask() = default; +void InProcessCommandBuffer::GpuTask::Run() { + if (once_closure_) { + std::move(once_closure_).Run(); + return; + } + DCHECK(repeating_closure_) << "Trying to run a OnceClosure more than once."; + repeating_closure_.Run(); +} + } // namespace gpu diff --git a/chromium/gpu/ipc/in_process_command_buffer.h b/chromium/gpu/ipc/in_process_command_buffer.h index ee55d73a258..818b968a998 100644 --- a/chromium/gpu/ipc/in_process_command_buffer.h +++ b/chromium/gpu/ipc/in_process_command_buffer.h @@ -131,7 +131,7 @@ class GL_IN_PROCESS_CONTEXT_EXPORT InProcessCommandBuffer size_t height, unsigned internalformat) override; void DestroyImage(int32_t id) override; - void SignalQuery(uint32_t query_id, const base::Closure& callback) override; + void SignalQuery(uint32_t query_id, base::OnceClosure callback) override; void CreateGpuFence(uint32_t gpu_fence_id, ClientGpuFence source) override; void GetGpuFence(uint32_t gpu_fence_id, base::OnceCallback<void(std::unique_ptr<gfx::GpuFence>)> @@ -144,7 +144,7 @@ class GL_IN_PROCESS_CONTEXT_EXPORT InProcessCommandBuffer uint64_t GenerateFenceSyncRelease() override; bool IsFenceSyncReleased(uint64_t release) override; void SignalSyncToken(const SyncToken& sync_token, - const base::Closure& callback) override; + base::OnceClosure callback) override; void WaitSyncTokenHint(const SyncToken& sync_token) override; bool CanWaitUnverifiedSyncToken(const SyncToken& sync_token) override; void SetSnapshotRequested() override; @@ -215,6 +215,8 @@ class GL_IN_PROCESS_CONTEXT_EXPORT InProcessCommandBuffer return decoder_->GetTransferCacheForTest(); } + static const int kGpuMemoryBufferClientId; + // The serializer interface to the GPU service (i.e. thread). class Service { public: @@ -229,11 +231,11 @@ class GL_IN_PROCESS_CONTEXT_EXPORT InProcessCommandBuffer virtual void Release() const = 0; // Queues a task to run as soon as possible. - virtual void ScheduleTask(const base::Closure& task) = 0; + virtual void ScheduleTask(base::OnceClosure task) = 0; // Schedules |callback| to run at an appropriate time for performing delayed // work. - virtual void ScheduleDelayedWork(const base::Closure& task) = 0; + virtual void ScheduleDelayedWork(base::OnceClosure task) = 0; virtual bool UseVirtualizedGLContexts() = 0; virtual SyncPointManager* sync_point_manager() = 0; @@ -303,14 +305,17 @@ class GL_IN_PROCESS_CONTEXT_EXPORT InProcessCommandBuffer void UpdateLastStateOnGpuThread(); void ScheduleDelayedWorkOnGpuThread(); bool MakeCurrent(); - base::Closure WrapCallback(const base::Closure& callback); - void QueueTask(bool out_of_order, const base::Closure& task); + base::OnceClosure WrapCallback(base::OnceClosure callback); + + void QueueOnceTask(bool out_of_order, base::OnceClosure task); + void QueueRepeatableTask(base::RepeatingClosure task); + void ProcessTasksOnGpuThread(); void CheckSequencedThread(); void OnWaitSyncTokenCompleted(const SyncToken& sync_token); void SignalSyncTokenOnGpuThread(const SyncToken& sync_token, - const base::Closure& callback); - void SignalQueryOnGpuThread(unsigned query_id, const base::Closure& callback); + base::OnceClosure callback); + void SignalQueryOnGpuThread(unsigned query_id, base::OnceClosure callback); void DestroyTransferBufferOnGpuThread(int32_t id); void CreateImageOnGpuThread(int32_t id, const gfx::GpuMemoryBufferHandle& handle, @@ -386,11 +391,22 @@ class GL_IN_PROCESS_CONTEXT_EXPORT InProcessCommandBuffer std::unique_ptr<base::SequenceChecker> sequence_checker_; base::Lock task_queue_lock_; - struct GpuTask { - GpuTask(const base::Closure& callback, uint32_t order_number); + class GpuTask { + public: + GpuTask(base::OnceClosure callback, uint32_t order_number); + GpuTask(base::RepeatingClosure callback, uint32_t order_number); ~GpuTask(); - base::Closure callback; - uint32_t order_number; + + uint32_t order_number() { return order_number_; } + bool is_repeatable() { return !!repeating_closure_; } + void Run(); + + private: + base::OnceClosure once_closure_; + base::RepeatingClosure repeating_closure_; + uint32_t order_number_; + + DISALLOW_COPY_AND_ASSIGN(GpuTask); }; base::queue<std::unique_ptr<GpuTask>> task_queue_; diff --git a/chromium/gpu/ipc/service/BUILD.gn b/chromium/gpu/ipc/service/BUILD.gn index 11b63a8a7ea..6b22443e3ab 100644 --- a/chromium/gpu/ipc/service/BUILD.gn +++ b/chromium/gpu/ipc/service/BUILD.gn @@ -43,6 +43,9 @@ component("service") { "switches.h", ] defines = [ "GPU_IPC_SERVICE_IMPLEMENTATION" ] + if (is_chromecast) { + defines += [ "IS_CHROMECAST" ] + } public_deps = [ "//base", "//ipc", diff --git a/chromium/gpu/ipc/service/direct_composition_child_surface_win.cc b/chromium/gpu/ipc/service/direct_composition_child_surface_win.cc index b8c5711996a..b95e029c853 100644 --- a/chromium/gpu/ipc/service/direct_composition_child_surface_win.cc +++ b/chromium/gpu/ipc/service/direct_composition_child_surface_win.cc @@ -210,7 +210,9 @@ void* DirectCompositionChildSurfaceWin::GetHandle() { gfx::SwapResult DirectCompositionChildSurfaceWin::SwapBuffers( const PresentationCallback& callback) { - // TODO(penghuang): Provide presentation feedback. https://crbug.com/776877 + // PresentationCallback is handled by DirectCompositionSurfaceWin. The child + // surface doesn't need provide presentation feedback. + DCHECK(!callback); ReleaseDrawTexture(false); return gfx::SwapResult::SWAP_ACK; } diff --git a/chromium/gpu/ipc/service/direct_composition_surface_win.cc b/chromium/gpu/ipc/service/direct_composition_surface_win.cc index 0df3457c877..9b009bbd275 100644 --- a/chromium/gpu/ipc/service/direct_composition_surface_win.cc +++ b/chromium/gpu/ipc/service/direct_composition_surface_win.cc @@ -35,6 +35,7 @@ #include "ui/gl/gl_image_dxgi.h" #include "ui/gl/gl_image_memory.h" #include "ui/gl/gl_surface_egl.h" +#include "ui/gl/gl_surface_presentation_helper.h" #include "ui/gl/scoped_make_current.h" #ifndef EGL_ANGLE_flexible_surface_compatibility @@ -1205,10 +1206,16 @@ bool DirectCompositionSurfaceWin::Initialize(gl::GLSurfaceFormat format) { return false; } - return RecreateRootSurface(); + if (!RecreateRootSurface()) + return false; + + presentation_helper_ = + std::make_unique<gl::GLSurfacePresentationHelper>(vsync_provider_.get()); + return true; } void DirectCompositionSurfaceWin::Destroy() { + presentation_helper_ = nullptr; if (default_surface_) { if (!eglDestroySurface(GetDisplay(), default_surface_)) { DLOG(ERROR) << "eglDestroySurface failed with error " @@ -1254,12 +1261,15 @@ bool DirectCompositionSurfaceWin::Resize(const gfx::Size& size, gfx::SwapResult DirectCompositionSurfaceWin::SwapBuffers( const PresentationCallback& callback) { + gl::GLSurfacePresentationHelper::ScopedSwapBuffers scoped_swap_buffers( + presentation_helper_.get(), callback); ui::ScopedReleaseCurrent release_current; - root_surface_->SwapBuffers(callback); + root_surface_->SwapBuffers(PresentationCallback()); layer_tree_->CommitAndClearPendingOverlays(); child_window_.ClearInvalidContents(); - return release_current.Restore() ? gfx::SwapResult::SWAP_ACK - : gfx::SwapResult::SWAP_FAILED; + if (!release_current.Restore()) + scoped_swap_buffers.set_result(gfx::SwapResult::SWAP_FAILED); + return scoped_swap_buffers.result(); } gfx::SwapResult DirectCompositionSurfaceWin::PostSubBuffer( @@ -1298,6 +1308,8 @@ bool DirectCompositionSurfaceWin::SupportsPostSubBuffer() { } bool DirectCompositionSurfaceWin::OnMakeCurrent(gl::GLContext* context) { + if (presentation_helper_) + presentation_helper_->OnMakeCurrent(context, this); if (root_surface_) return root_surface_->OnMakeCurrent(context); return true; diff --git a/chromium/gpu/ipc/service/direct_composition_surface_win.h b/chromium/gpu/ipc/service/direct_composition_surface_win.h index f135c1dfd20..a7c1b0d5001 100644 --- a/chromium/gpu/ipc/service/direct_composition_surface_win.h +++ b/chromium/gpu/ipc/service/direct_composition_surface_win.h @@ -18,6 +18,10 @@ #include "ui/gl/gl_image.h" #include "ui/gl/gl_surface_egl.h" +namespace gl { +class GLSurfacePresentationHelper; +} + namespace gpu { class DCLayerTree; @@ -107,6 +111,7 @@ class GPU_IPC_SERVICE_EXPORT DirectCompositionSurfaceWin bool is_hdr_ = false; bool has_alpha_ = true; std::unique_ptr<gfx::VSyncProvider> vsync_provider_; + std::unique_ptr<gl::GLSurfacePresentationHelper> presentation_helper_; scoped_refptr<DirectCompositionChildSurfaceWin> root_surface_; std::unique_ptr<DCLayerTree> layer_tree_; diff --git a/chromium/gpu/ipc/service/direct_composition_surface_win_unittest.cc b/chromium/gpu/ipc/service/direct_composition_surface_win_unittest.cc index 09c951772ce..fe35a50a82b 100644 --- a/chromium/gpu/ipc/service/direct_composition_surface_win_unittest.cc +++ b/chromium/gpu/ipc/service/direct_composition_surface_win_unittest.cc @@ -4,6 +4,7 @@ #include "gpu/ipc/service/direct_composition_surface_win.h" +#include "base/bind_helpers.h" #include "base/memory/ref_counted_memory.h" #include "base/memory/weak_ptr.h" #include "base/run_loop.h" @@ -42,8 +43,6 @@ bool CheckIfDCSupported() { return true; } -void EmptyPresentation(const gfx::PresentationFeedback&) {} - class TestImageTransportSurfaceDelegate : public ImageTransportSurfaceDelegate, public base::SupportsWeakPtr<TestImageTransportSurfaceDelegate> { @@ -178,7 +177,7 @@ TEST(DirectCompositionSurfaceTest, TestMakeCurrent) { EXPECT_TRUE(context1->MakeCurrent(surface1.get())); EXPECT_EQ(gfx::SwapResult::SWAP_ACK, - surface1->SwapBuffers(base::Bind(&EmptyPresentation))); + surface1->SwapBuffers(base::DoNothing())); EXPECT_TRUE(context1->IsCurrent(surface1.get())); @@ -247,8 +246,7 @@ TEST(DirectCompositionSurfaceTest, DXGIDCLayerSwitch) { EXPECT_FALSE(surface->SetDrawRectangle(gfx::Rect(0, 0, 100, 100))); EXPECT_TRUE(context->MakeCurrent(surface.get())); - EXPECT_EQ(gfx::SwapResult::SWAP_ACK, - surface->SwapBuffers(base::Bind(&EmptyPresentation))); + EXPECT_EQ(gfx::SwapResult::SWAP_ACK, surface->SwapBuffers(base::DoNothing())); EXPECT_TRUE(context->IsCurrent(surface.get())); @@ -263,8 +261,7 @@ TEST(DirectCompositionSurfaceTest, DXGIDCLayerSwitch) { surface->SetEnableDCLayers(false); - EXPECT_EQ(gfx::SwapResult::SWAP_ACK, - surface->SwapBuffers(base::Bind(&EmptyPresentation))); + EXPECT_EQ(gfx::SwapResult::SWAP_ACK, surface->SwapBuffers(base::DoNothing())); // Surface switched to use IDXGISwapChain, so must draw to entire // surface. @@ -360,8 +357,7 @@ TEST(DirectCompositionSurfaceTest, NoPresentTwice) { surface->GetLayerSwapChainForTesting(1); ASSERT_FALSE(swap_chain); - EXPECT_EQ(gfx::SwapResult::SWAP_ACK, - surface->SwapBuffers(base::Bind(&EmptyPresentation))); + EXPECT_EQ(gfx::SwapResult::SWAP_ACK, surface->SwapBuffers(base::DoNothing())); swap_chain = surface->GetLayerSwapChainForTesting(1); ASSERT_TRUE(swap_chain); @@ -374,8 +370,7 @@ TEST(DirectCompositionSurfaceTest, NoPresentTwice) { EXPECT_EQ(2u, last_present_count); surface->ScheduleDCLayer(params); - EXPECT_EQ(gfx::SwapResult::SWAP_ACK, - surface->SwapBuffers(base::Bind(&EmptyPresentation))); + EXPECT_EQ(gfx::SwapResult::SWAP_ACK, surface->SwapBuffers(base::DoNothing())); Microsoft::WRL::ComPtr<IDXGISwapChain1> swap_chain2 = surface->GetLayerSwapChainForTesting(1); @@ -393,8 +388,7 @@ TEST(DirectCompositionSurfaceTest, NoPresentTwice) { 0); surface->ScheduleDCLayer(params2); - EXPECT_EQ(gfx::SwapResult::SWAP_ACK, - surface->SwapBuffers(base::Bind(&EmptyPresentation))); + EXPECT_EQ(gfx::SwapResult::SWAP_ACK, surface->SwapBuffers(base::DoNothing())); Microsoft::WRL::ComPtr<IDXGISwapChain1> swap_chain3 = surface->GetLayerSwapChainForTesting(1); @@ -469,7 +463,7 @@ class DirectCompositionPixelTest : public testing::Test { glClear(GL_COLOR_BUFFER_BIT); EXPECT_EQ(gfx::SwapResult::SWAP_ACK, - surface_->SwapBuffers(base::Bind(&EmptyPresentation))); + surface_->SwapBuffers(base::DoNothing())); // Ensure DWM swap completed. Sleep(1000); @@ -544,7 +538,7 @@ class DirectCompositionVideoPixelTest : public DirectCompositionPixelTest { surface_->ScheduleDCLayer(params); EXPECT_EQ(gfx::SwapResult::SWAP_ACK, - surface_->SwapBuffers(base::Bind(&EmptyPresentation))); + surface_->SwapBuffers(base::DoNothing())); // Scaling up the swapchain with the same image should cause it to be // transformed again, but not presented again. @@ -556,7 +550,7 @@ class DirectCompositionVideoPixelTest : public DirectCompositionPixelTest { surface_->ScheduleDCLayer(params2); EXPECT_EQ(gfx::SwapResult::SWAP_ACK, - surface_->SwapBuffers(base::Bind(&EmptyPresentation))); + surface_->SwapBuffers(base::DoNothing())); Sleep(1000); if (check_color) { @@ -640,7 +634,7 @@ TEST_F(DirectCompositionPixelTest, SoftwareVideoSwapchain) { surface_->ScheduleDCLayer(params); EXPECT_EQ(gfx::SwapResult::SWAP_ACK, - surface_->SwapBuffers(base::Bind(&EmptyPresentation))); + surface_->SwapBuffers(base::DoNothing())); Sleep(1000); SkColor expected_color = SkColorSetRGB(0xff, 0xb7, 0xff); @@ -690,7 +684,7 @@ TEST_F(DirectCompositionPixelTest, VideoHandleSwapchain) { surface_->ScheduleDCLayer(params); EXPECT_EQ(gfx::SwapResult::SWAP_ACK, - surface_->SwapBuffers(base::Bind(&EmptyPresentation))); + surface_->SwapBuffers(base::DoNothing())); Sleep(1000); diff --git a/chromium/gpu/ipc/service/gpu_channel_test_common.h b/chromium/gpu/ipc/service/gpu_channel_test_common.h index 9e20b24417e..03cd2152ff5 100644 --- a/chromium/gpu/ipc/service/gpu_channel_test_common.h +++ b/chromium/gpu/ipc/service/gpu_channel_test_common.h @@ -2,6 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#ifndef GPU_IPC_SERVICE_GPU_CHANNEL_TEST_COMMON_H_ +#define GPU_IPC_SERVICE_GPU_CHANNEL_TEST_COMMON_H_ + #include <memory> #include "base/memory/ref_counted.h" @@ -50,3 +53,5 @@ class GpuChannelTestCommon : public testing::Test { }; } // namespace gpu + +#endif // GPU_IPC_SERVICE_GPU_CHANNEL_TEST_COMMON_H_ diff --git a/chromium/gpu/ipc/service/gpu_init.cc b/chromium/gpu/ipc/service/gpu_init.cc index a6a630a8bc1..f4cd63bae6d 100644 --- a/chromium/gpu/ipc/service/gpu_init.cc +++ b/chromium/gpu/ipc/service/gpu_init.cc @@ -19,6 +19,7 @@ #include "gpu/config/gpu_util.h" #include "gpu/ipc/service/gpu_watchdog_thread.h" #include "gpu/ipc/service/switches.h" +#include "ui/base/ui_base_features.h" #include "ui/gfx/switches.h" #include "ui/gl/gl_features.h" #include "ui/gl/gl_implementation.h" @@ -28,6 +29,7 @@ #if defined(USE_OZONE) #include "ui/ozone/public/ozone_platform.h" +#include "ui/ozone/public/ozone_switches.h" #endif #if defined(OS_WIN) @@ -39,29 +41,13 @@ namespace gpu { namespace { #if !defined(OS_MACOSX) -void CollectGraphicsInfo(GPUInfo* gpu_info) { +bool CollectGraphicsInfo(GPUInfo* gpu_info) { DCHECK(gpu_info); -#if defined(OS_FUCHSIA) - // TODO(crbug.com/707031): Implement this. - NOTIMPLEMENTED(); - return; -#else TRACE_EVENT0("gpu,startup", "Collect Graphics Info"); base::TimeTicks before_collect_context_graphics_info = base::TimeTicks::Now(); - CollectInfoResult result = CollectContextGraphicsInfo(gpu_info); - switch (result) { - case kCollectInfoFatalFailure: - LOG(ERROR) << "gpu::CollectGraphicsInfo failed (fatal)."; - break; - case kCollectInfoNonFatalFailure: - DVLOG(1) << "gpu::CollectGraphicsInfo failed (non-fatal)."; - break; - case kCollectInfoNone: - NOTREACHED(); - break; - case kCollectInfoSuccess: - break; - } + bool success = CollectContextGraphicsInfo(gpu_info); + if (!success) + LOG(ERROR) << "gpu::CollectGraphicsInfo failed."; #if defined(OS_WIN) if (gl::GetGLImplementation() == gl::kGLImplementationEGLGLES2 && @@ -75,16 +61,16 @@ void CollectGraphicsInfo(GPUInfo* gpu_info) { } #endif // defined(OS_WIN) - if (result != kCollectInfoFatalFailure) { + if (success) { base::TimeDelta collect_context_time = base::TimeTicks::Now() - before_collect_context_graphics_info; UMA_HISTOGRAM_TIMES("GPU.CollectContextGraphicsInfo", collect_context_time); } -#endif // defined(OS_FUCHSIA) + return success; } #endif // defined(OS_MACOSX) -#if defined(OS_LINUX) && !defined(OS_CHROMEOS) +#if defined(OS_LINUX) && !defined(OS_CHROMEOS) && !defined(IS_CHROMECAST) bool CanAccessNvidiaDeviceFile() { bool res = true; base::AssertBlockingAllowed(); @@ -94,7 +80,7 @@ bool CanAccessNvidiaDeviceFile() { } return res; } -#endif // defined(OS_LINUX) && !defined(OS_CHROMEOS) +#endif // OS_LINUX && !OS_CHROMEOS && !IS_CHROMECAST } // namespace @@ -107,13 +93,13 @@ GpuInit::~GpuInit() { bool GpuInit::InitializeAndStartSandbox(base::CommandLine* command_line, const GpuPreferences& gpu_preferences) { gpu_preferences_ = gpu_preferences; -#if !defined(OS_ANDROID) + // Blacklist decisions based on basic GPUInfo may not be final. It might + // need more context based GPUInfo. In such situations, switching to + // SwiftShader needs to wait until creating a context. + bool needs_more_info = false; +#if !defined(OS_ANDROID) && !defined(IS_CHROMECAST) if (!PopGPUInfoCache(&gpu_info_)) { - // Get vendor_id, device_id, driver_version from browser process through - // commandline switches. - // TODO(zmo): Collect basic GPU info (without a context) here instead of - // passing from browser process. - GetGpuInfoFromCommandLine(*command_line, &gpu_info_); + CollectBasicGraphicsInfo(command_line, &gpu_info_); } // Set keys for crash logging based on preliminary gpu info, in case we @@ -131,13 +117,14 @@ bool GpuInit::InitializeAndStartSandbox(base::CommandLine* command_line, gpu_feature_info_ = gpu::ComputeGpuFeatureInfo( gpu_info_, gpu_preferences.ignore_gpu_blacklist, gpu_preferences.disable_gpu_driver_bug_workarounds, - gpu_preferences.log_gpu_control_list_decisions, command_line); + gpu_preferences.log_gpu_control_list_decisions, command_line, + &needs_more_info); } if (gpu::SwitchableGPUsSupported(gpu_info_, *command_line)) { gpu::InitializeSwitchableGPUs( gpu_feature_info_.enabled_gpu_driver_bug_workarounds); } -#endif // OS_ANDROID +#endif // !OS_ANDROID && !IS_CHROMECAST gpu_info_.in_process_gpu = false; bool enable_watchdog = !gpu_preferences.disable_gpu_watchdog && @@ -197,10 +184,11 @@ bool GpuInit::InitializeAndStartSandbox(base::CommandLine* command_line, // may also have started at this point. ui::OzonePlatform::InitParams params; params.single_process = false; + params.using_mojo = command_line->HasSwitch(switches::kEnableDrmMojo); ui::OzonePlatform::InitializeForGPU(params); #endif - bool use_swiftshader = ShouldEnableSwiftShader(command_line); + bool use_swiftshader = ShouldEnableSwiftShader(command_line, needs_more_info); // Load and initialize the GL implementation and locate the GL entry points if // needed. This initialization may have already happened if running in the // browser process, for example. @@ -224,19 +212,17 @@ bool GpuInit::InitializeAndStartSandbox(base::CommandLine* command_line, // because the basic GPU information is passed down from the host process. #if !defined(OS_MACOSX) if (!use_swiftshader) { - CollectGraphicsInfo(&gpu_info_); - if (gpu_info_.context_info_state == gpu::kCollectInfoFatalFailure) + if (!CollectGraphicsInfo(&gpu_info_)) return false; gpu::SetKeysForCrashLogging(gpu_info_); gpu_feature_info_ = gpu::ComputeGpuFeatureInfo( gpu_info_, gpu_preferences.ignore_gpu_blacklist, gpu_preferences.disable_gpu_driver_bug_workarounds, - gpu_preferences.log_gpu_control_list_decisions, command_line); - use_swiftshader = ShouldEnableSwiftShader(command_line); + gpu_preferences.log_gpu_control_list_decisions, command_line, nullptr); + use_swiftshader = ShouldEnableSwiftShader(command_line, false); if (use_swiftshader) { gl::init::ShutdownGL(true); - gl_initialized = gl::init::InitializeGLNoExtensionsOneOff(); - if (!gl_initialized) { + if (!gl::init::InitializeGLNoExtensionsOneOff()) { VLOG(1) << "gl::init::InitializeGLNoExtensionsOneOff with SwiftShader " << "failed"; return false; @@ -257,8 +243,7 @@ bool GpuInit::InitializeAndStartSandbox(base::CommandLine* command_line, gl::init::SetDisabledExtensionsPlatform( gpu_feature_info_.disabled_extensions); } - gl_initialized = gl::init::InitializeExtensionSettingsOneOffPlatform(); - if (!gl_initialized) { + if (!gl::init::InitializeExtensionSettingsOneOffPlatform()) { VLOG(1) << "gl::init::InitializeExtensionSettingsOneOffPlatform failed"; return false; } @@ -300,56 +285,72 @@ bool GpuInit::InitializeAndStartSandbox(base::CommandLine* command_line, gles2::PassthroughCommandDecoderSupported(); init_successful_ = true; +#if defined(USE_OZONE) + ui::OzonePlatform::GetInstance()->AfterSandboxEntry(); +#endif return true; } +#if defined(OS_ANDROID) +void GpuInit::InitializeInProcess(base::CommandLine* command_line, + const GpuPreferences& gpu_preferences) { + gpu_preferences_ = gpu_preferences; + init_successful_ = true; + DCHECK(!ShouldEnableSwiftShader(command_line, false)); + + InitializeGLThreadSafe(command_line, gpu_preferences.ignore_gpu_blacklist, + gpu_preferences.disable_gpu_driver_bug_workarounds, + gpu_preferences.log_gpu_control_list_decisions, + &gpu_info_, &gpu_feature_info_); +} +#else void GpuInit::InitializeInProcess(base::CommandLine* command_line, - const GpuPreferences& gpu_preferences, - const GPUInfo* gpu_info, - const GpuFeatureInfo* gpu_feature_info) { + const GpuPreferences& gpu_preferences) { gpu_preferences_ = gpu_preferences; init_successful_ = true; #if defined(USE_OZONE) ui::OzonePlatform::InitParams params; params.single_process = true; - ui::OzonePlatform::InitializeForGPU(params); +#if defined(OS_CHROMEOS) + params.using_mojo = base::FeatureList::IsEnabled(features::kMash) || + command_line->HasSwitch(switches::kEnableDrmMojo); +#else + params.using_mojo = command_line->HasSwitch(switches::kEnableDrmMojo); #endif - - if (gpu_info && gpu_feature_info) { - gpu_info_ = *gpu_info; - gpu_feature_info_ = *gpu_feature_info; - } else { -#if !defined(OS_ANDROID) - if (!PopGPUInfoCache(&gpu_info_)) { - // TODO(zmo): Collect basic GPU info here instead. - gpu::GetGpuInfoFromCommandLine(*command_line, &gpu_info_); - } - if (!PopGpuFeatureInfoCache(&gpu_feature_info_)) { - gpu_feature_info_ = gpu::ComputeGpuFeatureInfo( - gpu_info_, gpu_preferences.ignore_gpu_blacklist, - gpu_preferences.disable_gpu_driver_bug_workarounds, - gpu_preferences.log_gpu_control_list_decisions, command_line); - } + ui::OzonePlatform::InitializeForGPU(params); + ui::OzonePlatform::GetInstance()->AfterSandboxEntry(); #endif + bool needs_more_info = false; +#if !defined(IS_CHROMECAST) + if (!PopGPUInfoCache(&gpu_info_)) { + CollectBasicGraphicsInfo(command_line, &gpu_info_); } - if (gpu::SwitchableGPUsSupported(gpu_info_, *command_line)) { - gpu::InitializeSwitchableGPUs( + if (!PopGpuFeatureInfoCache(&gpu_feature_info_)) { + gpu_feature_info_ = ComputeGpuFeatureInfo( + gpu_info_, gpu_preferences.ignore_gpu_blacklist, + gpu_preferences.disable_gpu_driver_bug_workarounds, + gpu_preferences.log_gpu_control_list_decisions, command_line, + &needs_more_info); + } + if (SwitchableGPUsSupported(gpu_info_, *command_line)) { + InitializeSwitchableGPUs( gpu_feature_info_.enabled_gpu_driver_bug_workarounds); } +#endif // !IS_CHROMECAST - bool use_swiftshader = ShouldEnableSwiftShader(command_line); + bool use_swiftshader = ShouldEnableSwiftShader(command_line, needs_more_info); if (!gl::init::InitializeGLNoExtensionsOneOff()) { VLOG(1) << "gl::init::InitializeGLNoExtensionsOneOff failed"; return; } if (!use_swiftshader) { - gpu::CollectContextGraphicsInfo(&gpu_info_); - gpu_feature_info_ = gpu::ComputeGpuFeatureInfo( + CollectContextGraphicsInfo(&gpu_info_); + gpu_feature_info_ = ComputeGpuFeatureInfo( gpu_info_, gpu_preferences.ignore_gpu_blacklist, gpu_preferences.disable_gpu_driver_bug_workarounds, - gpu_preferences.log_gpu_control_list_decisions, command_line); - use_swiftshader = ShouldEnableSwiftShader(command_line); + gpu_preferences.log_gpu_control_list_decisions, command_line, nullptr); + use_swiftshader = ShouldEnableSwiftShader(command_line, false); if (use_swiftshader) { gl::init::ShutdownGL(true); if (!gl::init::InitializeGLNoExtensionsOneOff()) { @@ -370,16 +371,19 @@ void GpuInit::InitializeInProcess(base::CommandLine* command_line, VLOG(1) << "gl::init::InitializeExtensionSettingsOneOffPlatform failed"; } } +#endif // OS_ANDROID -bool GpuInit::ShouldEnableSwiftShader(base::CommandLine* command_line) { +bool GpuInit::ShouldEnableSwiftShader(base::CommandLine* command_line, + bool blacklist_needs_more_info) { #if BUILDFLAG(ENABLE_SWIFTSHADER) if (gpu_preferences_.disable_software_rasterizer) return false; // Don't overwrite user preference. if (command_line->HasSwitch(switches::kUseGL)) return false; - if (gpu_feature_info_.status_values[GPU_FEATURE_TYPE_ACCELERATED_WEBGL] != - kGpuFeatureStatusEnabled) { + if (!blacklist_needs_more_info && + gpu_feature_info_.status_values[GPU_FEATURE_TYPE_ACCELERATED_WEBGL] != + kGpuFeatureStatusEnabled) { command_line->AppendSwitchASCII( switches::kUseGL, gl::kGLImplementationSwiftShaderForWebGLName); return true; diff --git a/chromium/gpu/ipc/service/gpu_init.h b/chromium/gpu/ipc/service/gpu_init.h index 9fd6b89d964..9ee296c3716 100644 --- a/chromium/gpu/ipc/service/gpu_init.h +++ b/chromium/gpu/ipc/service/gpu_init.h @@ -44,9 +44,7 @@ class GPU_IPC_SERVICE_EXPORT GpuInit { bool InitializeAndStartSandbox(base::CommandLine* command_line, const GpuPreferences& gpu_preferences); void InitializeInProcess(base::CommandLine* command_line, - const GpuPreferences& gpu_preferences, - const GPUInfo* gpu_info = nullptr, - const GpuFeatureInfo* gpu_feature_info = nullptr); + const GpuPreferences& gpu_preferences); const GPUInfo& gpu_info() const { return gpu_info_; } const GpuFeatureInfo& gpu_feature_info() const { return gpu_feature_info_; } @@ -64,7 +62,8 @@ class GPU_IPC_SERVICE_EXPORT GpuInit { GpuPreferences gpu_preferences_; bool init_successful_ = false; - bool ShouldEnableSwiftShader(base::CommandLine* command_line); + bool ShouldEnableSwiftShader(base::CommandLine* command_line, + bool blacklist_needs_more_info); void AdjustInfoToSwiftShader(); DISALLOW_COPY_AND_ASSIGN(GpuInit); }; diff --git a/chromium/gpu/ipc/service/gpu_memory_buffer_factory_io_surface.cc b/chromium/gpu/ipc/service/gpu_memory_buffer_factory_io_surface.cc index 472612bb40a..d739aad3c19 100644 --- a/chromium/gpu/ipc/service/gpu_memory_buffer_factory_io_surface.cc +++ b/chromium/gpu/ipc/service/gpu_memory_buffer_factory_io_surface.cc @@ -6,6 +6,7 @@ #include <vector> +#include "base/debug/dump_without_crashing.h" #include "base/logging.h" #include "gpu/GLES2/gl2extchromium.h" #include "ui/gfx/buffer_format_util.h" @@ -14,6 +15,15 @@ namespace gpu { +namespace { +// A GpuMemoryBuffer with client_id = 0 behaves like anonymous shared memory. +const int kAnonymousClientId = 0; + +// The maximum number of times to dump before throttling (to avoid sending +// thousands of crash dumps). +const int kMaxCrashDumps = 10; +} // namespace + GpuMemoryBufferFactoryIOSurface::GpuMemoryBufferFactoryIOSurface() { } @@ -28,26 +38,48 @@ GpuMemoryBufferFactoryIOSurface::CreateGpuMemoryBuffer( gfx::BufferUsage usage, int client_id, SurfaceHandle surface_handle) { - // Don't clear anonymous io surfaces. - bool should_clear = (client_id != 0); + DCHECK_NE(client_id, kAnonymousClientId); + + bool should_clear = true; base::ScopedCFTypeRef<IOSurfaceRef> io_surface( gfx::CreateIOSurface(size, format, should_clear)); - if (!io_surface) + if (!io_surface) { + LOG(ERROR) << "Failed to allocate IOSurface."; return gfx::GpuMemoryBufferHandle(); + } - // A GpuMemoryBuffer with client_id = 0 behaves like anonymous shared memory. - if (client_id != 0) { - base::AutoLock lock(io_surfaces_lock_); + gfx::GpuMemoryBufferHandle handle; + handle.type = gfx::IO_SURFACE_BUFFER; + handle.id = id; + handle.mach_port.reset(IOSurfaceCreateMachPort(io_surface)); + CHECK(handle.mach_port); + + // This IOSurface will be opened via mach port in the client process. It has + // been observed in https://crbug.com/574014 that these ports sometimes fail + // to be opened in the client process. It has further been observed in + // https://crbug.com/795649#c30 that these ports fail to be opened in creating + // process. To determine if these failures are independent, attempt to open + // the creating process first (and don't not return those that fail). + base::ScopedCFTypeRef<IOSurfaceRef> io_surface_from_mach_port( + IOSurfaceLookupFromMachPort(handle.mach_port.get())); + if (!io_surface_from_mach_port) { + LOG(ERROR) << "Failed to locally open IOSurface from mach port to be " + "returned to client, not returning to client."; + static int dump_counter = kMaxCrashDumps; + if (dump_counter) { + dump_counter -= 1; + base::debug::DumpWithoutCrashing(); + } + return gfx::GpuMemoryBufferHandle(); + } + { + base::AutoLock lock(io_surfaces_lock_); IOSurfaceMapKey key(id, client_id); DCHECK(io_surfaces_.find(key) == io_surfaces_.end()); io_surfaces_[key] = io_surface; } - gfx::GpuMemoryBufferHandle handle; - handle.type = gfx::IO_SURFACE_BUFFER; - handle.id = id; - handle.mach_port.reset(IOSurfaceCreateMachPort(io_surface)); return handle; } @@ -80,13 +112,17 @@ GpuMemoryBufferFactoryIOSurface::CreateImageForGpuMemoryBuffer( DCHECK_EQ(handle.type, gfx::IO_SURFACE_BUFFER); IOSurfaceMapKey key(handle.id, client_id); IOSurfaceMap::iterator it = io_surfaces_.find(key); - if (it == io_surfaces_.end()) + if (it == io_surfaces_.end()) { + DLOG(ERROR) << "Failed to find IOSurface based on key."; return scoped_refptr<gl::GLImage>(); + } scoped_refptr<gl::GLImageIOSurface> image( gl::GLImageIOSurface::Create(size, internalformat)); - if (!image->Initialize(it->second.get(), handle.id, format)) + if (!image->Initialize(it->second.get(), handle.id, format)) { + DLOG(ERROR) << "Failed to initialize GLImage for IOSurface."; return scoped_refptr<gl::GLImage>(); + } return image; } @@ -97,20 +133,43 @@ GpuMemoryBufferFactoryIOSurface::CreateAnonymousImage(const gfx::Size& size, gfx::BufferUsage usage, unsigned internalformat, bool* is_cleared) { - // Note that the child id doesn't matter since the texture will never be - // directly exposed to other processes, only via a mailbox. - gfx::GpuMemoryBufferHandle handle = CreateGpuMemoryBuffer( - gfx::GpuMemoryBufferId(next_anonymous_image_id_++), size, format, usage, - 0 /* client_id */, gpu::kNullSurfaceHandle); + bool should_clear = false; + base::ScopedCFTypeRef<IOSurfaceRef> io_surface( + gfx::CreateIOSurface(size, format, should_clear)); + if (!io_surface) { + LOG(ERROR) << "Failed to allocate IOSurface."; + return nullptr; + } - base::ScopedCFTypeRef<IOSurfaceRef> io_surface; - io_surface.reset(IOSurfaceLookupFromMachPort(handle.mach_port.get())); - DCHECK_NE(nullptr, io_surface.get()); + // This IOSurface does not require passing via a mach port, but attempt to + // locally open via a mach port to gather data to include in a Radar about + // this failure. + // https://crbug.com/795649 + gfx::ScopedRefCountedIOSurfaceMachPort mach_port( + IOSurfaceCreateMachPort(io_surface)); + if (mach_port) { + base::ScopedCFTypeRef<IOSurfaceRef> io_surface_from_mach_port( + IOSurfaceLookupFromMachPort(mach_port.get())); + if (!io_surface_from_mach_port) { + LOG(ERROR) << "Failed to locally open anonymous IOSurface mach port " + "(ignoring failure)."; + static int dump_counter = kMaxCrashDumps; + if (dump_counter) { + dump_counter -= 1; + base::debug::DumpWithoutCrashing(); + } + } + } else { + LOG(ERROR) << "Failed to create IOSurface mach port."; + } + gfx::GenericSharedMemoryId image_id(++next_anonymous_image_id_); scoped_refptr<gl::GLImageIOSurface> image( gl::GLImageIOSurface::Create(size, internalformat)); - if (!image->Initialize(io_surface.get(), handle.id, format)) + if (!image->Initialize(io_surface.get(), image_id, format)) { + DLOG(ERROR) << "Failed to initialize anonymous GLImage."; return scoped_refptr<gl::GLImage>(); + } *is_cleared = false; return image; diff --git a/chromium/gpu/ipc/service/gpu_vsync_provider_win.cc b/chromium/gpu/ipc/service/gpu_vsync_provider_win.cc index 7c387fec43b..4b1daf15372 100644 --- a/chromium/gpu/ipc/service/gpu_vsync_provider_win.cc +++ b/chromium/gpu/ipc/service/gpu_vsync_provider_win.cc @@ -669,7 +669,11 @@ bool GpuVSyncProviderWin::GetVSyncParametersIfAvailable( return false; } -bool GpuVSyncProviderWin::SupportGetVSyncParametersIfAvailable() { +bool GpuVSyncProviderWin::SupportGetVSyncParametersIfAvailable() const { + return false; +} + +bool GpuVSyncProviderWin::IsHWClock() const { return false; } diff --git a/chromium/gpu/ipc/service/gpu_vsync_provider_win.h b/chromium/gpu/ipc/service/gpu_vsync_provider_win.h index d9ab1d3f17c..a18fb2f7426 100644 --- a/chromium/gpu/ipc/service/gpu_vsync_provider_win.h +++ b/chromium/gpu/ipc/service/gpu_vsync_provider_win.h @@ -33,7 +33,8 @@ class GPU_IPC_SERVICE_EXPORT GpuVSyncProviderWin : public gfx::VSyncProvider { void GetVSyncParameters(const UpdateVSyncCallback& callback) override; bool GetVSyncParametersIfAvailable(base::TimeTicks* timebase, base::TimeDelta* interval) override; - bool SupportGetVSyncParametersIfAvailable() override; + bool SupportGetVSyncParametersIfAvailable() const override; + bool IsHWClock() const override; private: void OnVSync(base::TimeTicks timestamp, base::TimeDelta interval); diff --git a/chromium/gpu/ipc/service/gpu_watchdog_thread.cc b/chromium/gpu/ipc/service/gpu_watchdog_thread.cc index de3e362ea54..a39c10054eb 100644 --- a/chromium/gpu/ipc/service/gpu_watchdog_thread.cc +++ b/chromium/gpu/ipc/service/gpu_watchdog_thread.cc @@ -158,8 +158,11 @@ GpuWatchdogThread::~GpuWatchdogThread() { #if defined(USE_X11) if (tty_file_) fclose(tty_file_); - XDestroyWindow(display_, window_); - XCloseDisplay(display_); + if (display_) { + DCHECK(window_); + XDestroyWindow(display_, window_); + XCloseDisplay(display_); + } #endif watched_message_loop_->RemoveTaskObserver(&task_observer_); @@ -243,8 +246,7 @@ void GpuWatchdogThread::OnCheck(bool after_suspend) { // Post a task to the monitored thread that does nothing but wake up the // TaskObserver. Any other tasks that are pending on the watched thread will // also wake up the observer. This simply ensures there is at least one. - watched_message_loop_->task_runner()->PostTask(FROM_HERE, - base::Bind(&base::DoNothing)); + watched_message_loop_->task_runner()->PostTask(FROM_HERE, base::DoNothing()); // Post a task to the watchdog thread to exit if the monitored thread does // not respond in time. @@ -283,8 +285,8 @@ void GpuWatchdogThread::OnCheckTimeout() { // Post a task that does nothing on the watched thread to bump its priority // and make it more likely to get scheduled. - watched_message_loop_->task_runner()->PostTask( - FROM_HERE, base::Bind(&base::DoNothing)); + watched_message_loop_->task_runner()->PostTask(FROM_HERE, + base::DoNothing()); return; } @@ -312,46 +314,48 @@ void GpuWatchdogThread::DeliberatelyTerminateToRecoverFromHang() { #endif #if defined(USE_X11) - XWindowAttributes attributes; - XGetWindowAttributes(display_, window_, &attributes); - - XSelectInput(display_, window_, PropertyChangeMask); - SetupXChangeProp(); - - XFlush(display_); - - // We wait for the property change event with a timeout. If it arrives we know - // that X is responsive and is not the cause of the watchdog trigger, so we - // should - // terminate. If it times out, it may be due to X taking a long time, but - // terminating won't help, so ignore the watchdog trigger. - XEvent event_return; - base::TimeTicks deadline = base::TimeTicks::Now() + timeout_; - while (true) { - base::TimeDelta delta = deadline - base::TimeTicks::Now(); - if (delta < base::TimeDelta()) { - return; - } else { - while (XCheckWindowEvent(display_, window_, PropertyChangeMask, - &event_return)) { - if (MatchXEventAtom(&event_return)) - break; - } - struct pollfd fds[1]; - fds[0].fd = XConnectionNumber(display_); - fds[0].events = POLLIN; - int status = poll(fds, 1, delta.InMilliseconds()); - if (status == -1) { - if (errno == EINTR) { - continue; - } else { - LOG(FATAL) << "Lost X connection, aborting."; - break; - } - } else if (status == 0) { + if (display_) { + DCHECK(window_); + XWindowAttributes attributes; + XGetWindowAttributes(display_, window_, &attributes); + + XSelectInput(display_, window_, PropertyChangeMask); + SetupXChangeProp(); + + XFlush(display_); + + // We wait for the property change event with a timeout. If it arrives we + // know that X is responsive and is not the cause of the watchdog trigger, + // so we should terminate. If it times out, it may be due to X taking a long + // time, but terminating won't help, so ignore the watchdog trigger. + XEvent event_return; + base::TimeTicks deadline = base::TimeTicks::Now() + timeout_; + while (true) { + base::TimeDelta delta = deadline - base::TimeTicks::Now(); + if (delta < base::TimeDelta()) { return; } else { - continue; + while (XCheckWindowEvent(display_, window_, PropertyChangeMask, + &event_return)) { + if (MatchXEventAtom(&event_return)) + break; + } + struct pollfd fds[1]; + fds[0].fd = XConnectionNumber(display_); + fds[0].events = POLLIN; + int status = poll(fds, 1, delta.InMilliseconds()); + if (status == -1) { + if (errno == EINTR) { + continue; + } else { + LOG(FATAL) << "Lost X connection, aborting."; + break; + } + } else if (status == 0) { + return; + } else { + continue; + } } } } @@ -426,13 +430,17 @@ void GpuWatchdogThread::DeliberatelyTerminateToRecoverFromHang() { #if defined(USE_X11) void GpuWatchdogThread::SetupXServer() { display_ = XOpenDisplay(NULL); - window_ = XCreateWindow(display_, DefaultRootWindow(display_), 0, 0, 1, 1, 0, - CopyFromParent, InputOutput, CopyFromParent, 0, NULL); - atom_ = XInternAtom(display_, "CHECK", x11::False); + if (display_) { + window_ = + XCreateWindow(display_, DefaultRootWindow(display_), 0, 0, 1, 1, 0, + CopyFromParent, InputOutput, CopyFromParent, 0, NULL); + atom_ = XInternAtom(display_, "CHECK", x11::False); + } host_tty_ = GetActiveTTY(); } void GpuWatchdogThread::SetupXChangeProp() { + DCHECK(display_); XChangeProperty(display_, window_, atom_, XA_STRING, 8, PropModeReplace, text, (arraysize(text) - 1)); } diff --git a/chromium/gpu/ipc/service/image_transport_surface_fuchsia.cc b/chromium/gpu/ipc/service/image_transport_surface_fuchsia.cc index 8818adfe765..f2feaed4c02 100644 --- a/chromium/gpu/ipc/service/image_transport_surface_fuchsia.cc +++ b/chromium/gpu/ipc/service/image_transport_surface_fuchsia.cc @@ -6,8 +6,8 @@ #include "base/logging.h" #include "ui/gl/gl_surface.h" -#include "ui/gl/gl_surface_osmesa.h" #include "ui/gl/gl_surface_stub.h" +#include "ui/gl/init/gl_factory.h" namespace gpu { @@ -16,14 +16,12 @@ scoped_refptr<gl::GLSurface> ImageTransportSurface::CreateNativeSurface( base::WeakPtr<ImageTransportSurfaceDelegate> delegate, SurfaceHandle surface_handle, gl::GLSurfaceFormat format) { - if (gl::GetGLImplementation() == gl::kGLImplementationOSMesaGL) { - return gl::InitializeGLSurfaceWithFormat( - new gl::GLSurfaceOSMesa(format, gfx::Size(1, 1)), format); + if (gl::GetGLImplementation() == gl::kGLImplementationMockGL || + gl::GetGLImplementation() == gl::kGLImplementationStubGL) { + return new gl::GLSurfaceStub; } - DCHECK(gl::GetGLImplementation() == gl::kGLImplementationMockGL || - gl::GetGLImplementation() == gl::kGLImplementationStubGL); - return new gl::GLSurfaceStub; + return gl::init::CreateViewGLSurface(surface_handle); } } // namespace gpu diff --git a/chromium/gpu/ipc/service/image_transport_surface_mac.mm b/chromium/gpu/ipc/service/image_transport_surface_mac.mm index d67f9edc4c2..b13d6397734 100644 --- a/chromium/gpu/ipc/service/image_transport_surface_mac.mm +++ b/chromium/gpu/ipc/service/image_transport_surface_mac.mm @@ -53,6 +53,7 @@ scoped_refptr<gl::GLSurface> ImageTransportSurface::CreateNativeSurface( case gl::kGLImplementationDesktopGL: case gl::kGLImplementationDesktopGLCoreProfile: case gl::kGLImplementationAppleGL: + case gl::kGLImplementationEGLGLES2: return base::WrapRefCounted<gl::GLSurface>( new ImageTransportSurfaceOverlayMac(delegate)); case gl::kGLImplementationMockGL: diff --git a/chromium/gpu/ipc/service/image_transport_surface_overlay_mac.h b/chromium/gpu/ipc/service/image_transport_surface_overlay_mac.h index 3838521c04d..89abf863160 100644 --- a/chromium/gpu/ipc/service/image_transport_surface_overlay_mac.h +++ b/chromium/gpu/ipc/service/image_transport_surface_overlay_mac.h @@ -5,15 +5,12 @@ #ifndef GPU_IPC_SERVICE_IMAGE_TRANSPORT_SURFACE_OVERLAY_MAC_H_ #define GPU_IPC_SERVICE_IMAGE_TRANSPORT_SURFACE_OVERLAY_MAC_H_ -#include <list> -#include <memory> #include <vector> #import "base/mac/scoped_nsobject.h" -#include "base/timer/timer.h" #include "gpu/ipc/service/command_buffer_stub.h" #include "gpu/ipc/service/image_transport_surface.h" -#include "ui/base/cocoa/remote_layer_api.h" +#include "ui/gl/gl_bindings.h" #include "ui/gl/gl_surface.h" #include "ui/gl/gpu_switching_observer.h" diff --git a/chromium/gpu/ipc/service/image_transport_surface_overlay_mac.mm b/chromium/gpu/ipc/service/image_transport_surface_overlay_mac.mm index 8cad9b07e04..3ac5d2293c7 100644 --- a/chromium/gpu/ipc/service/image_transport_surface_overlay_mac.mm +++ b/chromium/gpu/ipc/service/image_transport_surface_overlay_mac.mm @@ -4,24 +4,7 @@ #include "gpu/ipc/service/image_transport_surface_overlay_mac.h" -#include <CoreGraphics/CoreGraphics.h> -#include <IOSurface/IOSurface.h> -#include <OpenGL/CGLRenderers.h> -#include <OpenGL/CGLTypes.h> -#include <OpenGL/gl.h> -#include <stddef.h> - -#include <algorithm> - -// This type consistently causes problem on Mac, and needs to be dealt with -// in a systemic way. -// http://crbug.com/517208 -#ifndef GL_OES_EGL_image -typedef void* GLeglImageOES; -#endif - #include "base/bind.h" -#include "base/bind_helpers.h" #include "base/command_line.h" #include "base/metrics/histogram_macros.h" #include "base/threading/thread_task_runner_handle.h" @@ -32,12 +15,8 @@ typedef void* GLeglImageOES; #include "gpu/ipc/service/image_transport_surface_delegate.h" #include "ui/accelerated_widget_mac/ca_layer_tree_coordinator.h" #include "ui/accelerated_widget_mac/io_surface_context.h" -#include "ui/base/cocoa/animation_utils.h" #include "ui/base/cocoa/remote_layer_api.h" #include "ui/base/ui_base_switches.h" -#include "ui/gfx/geometry/rect_conversions.h" -#include "ui/gfx/swap_result.h" -#include "ui/gfx/transform.h" #include "ui/gl/ca_renderer_layer_params.h" #include "ui/gl/gl_context.h" #include "ui/gl/gl_fence.h" @@ -54,9 +33,6 @@ void CheckGLErrors(const char* msg) { } } -void IOSurfaceContextNoOp(scoped_refptr<ui::IOSurfaceContext>) { -} - } // namespace namespace gpu { @@ -390,7 +366,10 @@ void ImageTransportSurfaceOverlayMac::OnGpuSwitched() { // this is to avoid creating-then-destroying the context for every image // transport surface that is observing the GPU switch. base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&IOSurfaceContextNoOp, context_on_new_gpu)); + FROM_HERE, + base::Bind( + base::DoNothing::Repeatedly<scoped_refptr<ui::IOSurfaceContext>>(), + context_on_new_gpu)); } } // namespace gpu diff --git a/chromium/gpu/ipc/service/raster_command_buffer_stub.cc b/chromium/gpu/ipc/service/raster_command_buffer_stub.cc index de0648d5a7b..49a08a3bf49 100644 --- a/chromium/gpu/ipc/service/raster_command_buffer_stub.cc +++ b/chromium/gpu/ipc/service/raster_command_buffer_stub.cc @@ -133,8 +133,8 @@ gpu::ContextResult RasterCommandBufferStub::Initialize( command_buffer_ = std::make_unique<CommandBufferService>( this, context_group_->transfer_buffer_manager()); - auto decoder = std::make_unique<raster::RasterDecoder>( - this, command_buffer_.get(), manager->outputter(), context_group_.get()); + std::unique_ptr<raster::RasterDecoder> decoder(raster::RasterDecoder::Create( + this, command_buffer_.get(), manager->outputter(), context_group_.get())); sync_point_client_state_ = channel_->sync_point_manager()->CreateSyncPointClientState( |