| // Copyright 2020 The Chromium Authors | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #include "gpu/command_buffer/client/shared_image_interface.h" | |
| #include <GLES2/gl2.h> | |
| #include "base/functional/callback_helpers.h" | |
| #include "base/logging.h" | |
| #include "base/notimplemented.h" | |
| #include "base/notreached.h" | |
| #include "base/process/memory.h" | |
| #include "components/viz/common/resources/shared_image_format_utils.h" | |
| #include "gpu/command_buffer/client/client_shared_image.h" | |
| #include "gpu/command_buffer/common/shared_image_usage.h" | |
| #if BUILDFLAG(IS_WIN) | |
| #include "ui/gfx/win/d3d_shared_fence.h" | |
| #endif | |
| namespace gpu { | |
| // static | |
| void SharedImageInterface::CreateSharedMemoryRegionFromSIInfo( | |
| const SharedImageInfo& si_info, | |
| base::WritableSharedMemoryMapping& mapping, | |
| gfx::GpuMemoryBufferHandle& handle) { | |
| DCHECK(gpu::IsValidClientUsage(si_info.usage)) | |
| << static_cast<uint32_t>(si_info.usage); | |
| DCHECK_EQ(si_info.usage, | |
| gpu::SharedImageUsageSet(gpu::SHARED_IMAGE_USAGE_CPU_WRITE_ONLY)); | |
| #if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) | |
| CHECK(!si_info.format.PrefersExternalSampler()) << si_info.format.ToString(); | |
| #endif | |
| const size_t buffer_size = | |
| viz::SharedMemorySizeForSharedImageFormat(si_info.format, si_info.size) | |
| .value(); | |
| auto shared_memory_region = | |
| base::UnsafeSharedMemoryRegion::Create(buffer_size); | |
| if (!shared_memory_region.IsValid()) { | |
| DLOG(ERROR) << "base::UnsafeSharedMemoryRegion::Create() for SharedImage " | |
| "with SHARED_IMAGE_USAGE_CPU_WRITE_ONLY fails!"; | |
| base::TerminateBecauseOutOfMemory(buffer_size); | |
| } | |
| mapping = shared_memory_region.Map(); | |
| if (!mapping.IsValid()) { | |
| DLOG(ERROR) << "shared_memory_region.Map() for " | |
| "SHARED_IMAGE_USAGE_CPU_WRITE_ONLY fails!"; | |
| base::TerminateBecauseOutOfMemory(buffer_size); | |
| } | |
| handle = gfx::GpuMemoryBufferHandle(std::move(shared_memory_region)); | |
| handle.offset = 0; | |
| handle.stride = static_cast<int32_t>( | |
| viz::SharedMemoryRowSizeForSharedImageFormat( | |
| si_info.format, /*plane_index=*/0, si_info.size.width()) | |
| .value()); | |
| } | |
| gpu::SharedImageUsageSet SharedImageInterface::GetCpuSIUsage( | |
| gfx::BufferUsage buffer_usage) { | |
| switch (buffer_usage) { | |
| case gfx::BufferUsage::GPU_READ: | |
| case gfx::BufferUsage::SCANOUT: | |
| case gfx::BufferUsage::SCANOUT_FRONT_RENDERING: | |
| case gfx::BufferUsage::SCANOUT_VDA_WRITE: | |
| case gfx::BufferUsage::PROTECTED_SCANOUT: | |
| case gfx::BufferUsage::PROTECTED_SCANOUT_VDA_WRITE: | |
| return gpu::SharedImageUsageSet(); | |
| case gfx::BufferUsage::SCANOUT_VEA_CPU_READ: | |
| return gpu::SHARED_IMAGE_USAGE_CPU_READ; | |
| case gfx::BufferUsage::SCANOUT_CAMERA_READ_WRITE: | |
| case gfx::BufferUsage::SCANOUT_CPU_READ_WRITE: | |
| case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE: | |
| case gfx::BufferUsage::CAMERA_AND_CPU_READ_WRITE: | |
| case gfx::BufferUsage::VEA_READ_CAMERA_AND_CPU_READ_WRITE: | |
| return gpu::SHARED_IMAGE_USAGE_CPU_READ | | |
| gpu::SHARED_IMAGE_USAGE_CPU_WRITE_ONLY; | |
| } | |
| } | |
| SharedImageInterface::SharedImageInterface() | |
| : holder_(base::MakeRefCounted<SharedImageInterfaceHolder>(this)) {} | |
| SharedImageInterface::~SharedImageInterface() = default; | |
| scoped_refptr<ClientSharedImage> SharedImageInterface::CreateSharedImage( | |
| const SharedImageInfo& si_info, | |
| gpu::SurfaceHandle surface_handle, | |
| gfx::BufferUsage buffer_usage, | |
| std::optional<SharedImagePoolId> pool_id) { | |
| NOTREACHED(); | |
| } | |
| scoped_refptr<ClientSharedImage> SharedImageInterface::NotifyMailboxAdded( | |
| const Mailbox& /*mailbox*/, | |
| viz::SharedImageFormat /*format*/, | |
| const gfx::Size& /*size*/, | |
| const gfx::ColorSpace& /*color_space*/, | |
| GrSurfaceOrigin /*surface_origin*/, | |
| SkAlphaType /*alpha_type*/, | |
| SharedImageUsageSet /*usage*/, | |
| uint32_t /*texture_target*/, | |
| std::string_view /*debug_label*/) { | |
| return nullptr; | |
| } | |
| void SharedImageInterface::CopyToGpuMemoryBuffer( | |
| std::vector<SyncToken> sync_tokens, | |
| const Mailbox& mailbox) { | |
| NOTREACHED(); | |
| } | |
| void SharedImageInterface::CopyToGpuMemoryBufferAsync( | |
| std::vector<SyncToken> sync_tokens, | |
| const Mailbox& mailbox, | |
| base::OnceCallback<void(bool)> callback) { | |
| NOTREACHED(); | |
| } | |
| void SharedImageInterface::CopyNativeGmbToSharedMemoryAsync( | |
| gfx::GpuMemoryBufferHandle buffer_handle, | |
| base::UnsafeSharedMemoryRegion memory_region, | |
| base::OnceCallback<void(bool)> callback) { | |
| NOTREACHED(); | |
| } | |
| void SharedImageInterface::Release() const { | |
| bool should_destroy = false; | |
| { | |
| base::AutoLock auto_lock(holder_->lock_); | |
| if (base::subtle::RefCountedThreadSafeBase::Release()) { | |
| ANALYZER_SKIP_THIS_PATH(); | |
| holder_->OnDestroy(); | |
| should_destroy = true; | |
| } | |
| } | |
| if (should_destroy) { | |
| delete this; | |
| } | |
| } | |
| #if BUILDFLAG(IS_WIN) | |
| void SharedImageInterface::UpdateSharedImage( | |
| const SyncToken& sync_token, | |
| scoped_refptr<gfx::D3DSharedFence> d3d_shared_fence, | |
| const Mailbox& mailbox) { | |
| NOTIMPLEMENTED_LOG_ONCE(); | |
| } | |
| #endif // BUILDFLAG(IS_WIN) | |
| void SharedImageInterface::CreateSharedImagePool( | |
| const SharedImagePoolId& pool_id, | |
| mojo::PendingRemote<mojom::SharedImagePoolClientInterface> client_remote) { | |
| NOTREACHED(); | |
| } | |
| void SharedImageInterface::DestroySharedImagePool( | |
| const SharedImagePoolId& pool_id) { | |
| NOTREACHED(); | |
| } | |
| bool SharedImageInterface::IsLost() const { | |
| NOTREACHED(); | |
| } | |
| bool SharedImageInterface::AddGpuChannelLostObserver( | |
| GpuChannelLostObserver* observer) { | |
| NOTREACHED(); | |
| } | |
| void SharedImageInterface::RemoveGpuChannelLostObserver( | |
| GpuChannelLostObserver* observer) { | |
| NOTREACHED(); | |
| } | |
| void SharedImageInterface::SignalSyncToken(std::vector<SyncToken> sync_tokens, | |
| base::OnceClosure callback) { | |
| NOTREACHED(); | |
| } | |
| SharedImageInterfaceHolder::SharedImageInterfaceHolder( | |
| SharedImageInterface* sii) | |
| : sii_(sii) {} | |
| SharedImageInterfaceHolder::~SharedImageInterfaceHolder() = default; | |
| scoped_refptr<SharedImageInterface> SharedImageInterfaceHolder::Get() { | |
| base::AutoLock auto_lock(lock_); | |
| return scoped_refptr<SharedImageInterface>(sii_); | |
| } | |
| void SharedImageInterfaceHolder::OnDestroy() { | |
| lock_.AssertAcquired(); | |
| sii_ = nullptr; | |
| } | |
| } // namespace gpu |