#include "gpu/command_buffer/client/test_shared_image_interface.h"
#include <GLES2/gl2.h>
#include <GLES2/gl2extchromium.h>
#include <utility>
#if BUILDFLAG(IS_FUCHSIA)
#include <fuchsia/sysmem2/cpp/fidl.h>
#include <lib/sys/cpp/component_context.h>
#endif
#include "base/check.h"
#include "base/notreached.h"
#include "build/build_config.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_capabilities.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/buffer_format_util.h"
#include "ui/gfx/gpu_fence.h"
#include "ui/gfx/gpu_memory_buffer.h"
#if BUILDFLAG(IS_FUCHSIA)
#include "base/fuchsia/fuchsia_logging.h"
#include "base/fuchsia/koid.h"
#include "base/fuchsia/process_context.h"
#endif
namespace gpu {
namespace {
gfx::GpuMemoryBufferType GetNativeBufferType() { … }
gfx::GpuMemoryBufferHandle CreateGMBHandle(
const gfx::BufferFormat& buffer_format,
const gfx::Size& size,
gfx::BufferUsage buffer_usage) { … }
}
#if BUILDFLAG(IS_FUCHSIA)
class TestBufferCollection {
public:
TestBufferCollection(zx::eventpair handle, zx::channel collection_token)
: handle_(std::move(handle)) {
sysmem_allocator_ = base::ComponentContextForProcess()
->svc()
->Connect<fuchsia::sysmem2::Allocator>();
sysmem_allocator_.set_error_handler([](zx_status_t status) {
ZX_LOG(FATAL, status)
<< "The fuchsia.sysmem.Allocator channel was terminated.";
});
fuchsia::sysmem2::AllocatorSetDebugClientInfoRequest set_debug_request;
set_debug_request.set_name("CrTestBufferCollection");
set_debug_request.set_id(base::GetCurrentProcId());
sysmem_allocator_->SetDebugClientInfo(std::move(set_debug_request));
fuchsia::sysmem2::AllocatorBindSharedCollectionRequest bind_shared_request;
bind_shared_request.set_token(fidl::InterfaceHandle<fuchsia::sysmem2::BufferCollectionToken>(
std::move(collection_token)));
bind_shared_request.set_buffer_collection_request(buffers_collection_.NewRequest());
sysmem_allocator_->BindSharedCollection(std::move(bind_shared_request));
fuchsia::sysmem2::BufferCollectionSetConstraintsRequest set_constraints_request;
auto& buffer_constraints = *set_constraints_request.mutable_constraints();
buffer_constraints.mutable_usage()->set_cpu(fuchsia::sysmem2::CPU_USAGE_READ);
zx_status_t status = buffers_collection_->SetConstraints(std::move(set_constraints_request));
ZX_CHECK(status == ZX_OK, status) << "BufferCollection::SetConstraints()";
}
TestBufferCollection(const TestBufferCollection&) = delete;
TestBufferCollection& operator=(const TestBufferCollection&) = delete;
~TestBufferCollection() { buffers_collection_->Release(); }
size_t GetNumBuffers() {
if (!buffer_collection_info_) {
fuchsia::sysmem2::BufferCollection_WaitForAllBuffersAllocated_Result wait_result;
zx_status_t status =
buffers_collection_->WaitForAllBuffersAllocated(&wait_result);
if (status != ZX_OK) {
ZX_LOG(FATAL, status) <<
"BufferCollection::WaitForAllBuffersAllocated() (status)";
} else if (wait_result.is_framework_err()) {
LOG(FATAL) <<
"BufferCollection::WaitForAllBuffersAllocated (framework_err): " <<
fidl::ToUnderlying(wait_result.framework_err());
} else if (!wait_result.is_response()) {
LOG(FATAL) << "BufferCollection::WaitForAllBuffersAllocated (err)" <<
static_cast<uint32_t>(wait_result.err());
}
auto info = std::move(*wait_result.response().mutable_buffer_collection_info());
buffer_collection_info_ = std::move(info);
}
return buffer_collection_info_->buffers().size();
}
private:
zx::eventpair handle_;
fuchsia::sysmem2::AllocatorPtr sysmem_allocator_;
fuchsia::sysmem2::BufferCollectionSyncPtr buffers_collection_;
std::optional<fuchsia::sysmem2::BufferCollectionInfo>
buffer_collection_info_;
};
#endif
TestSharedImageInterface::TestSharedImageInterface() { … }
TestSharedImageInterface::~TestSharedImageInterface() = default;
scoped_refptr<ClientSharedImage>
TestSharedImageInterface::CreateSharedImage(const SharedImageInfo& si_info,
SurfaceHandle surface_handle) { … }
scoped_refptr<ClientSharedImage>
TestSharedImageInterface::CreateSharedImage(
const SharedImageInfo& si_info,
base::span<const uint8_t> pixel_data) { … }
scoped_refptr<ClientSharedImage>
TestSharedImageInterface::CreateSharedImage(const SharedImageInfo& si_info,
SurfaceHandle surface_handle,
gfx::BufferUsage buffer_usage) { … }
scoped_refptr<ClientSharedImage>
TestSharedImageInterface::CreateSharedImage(
const SharedImageInfo& si_info,
SurfaceHandle surface_handle,
gfx::BufferUsage buffer_usage,
gfx::GpuMemoryBufferHandle buffer_handle) { … }
scoped_refptr<ClientSharedImage>
TestSharedImageInterface::CreateSharedImage(
const SharedImageInfo& si_info,
gfx::GpuMemoryBufferHandle buffer_handle) { … }
SharedImageInterface::SharedImageMapping
TestSharedImageInterface::CreateSharedImage(
const SharedImageInfo& si_info) { … }
void TestSharedImageInterface::UpdateSharedImage(
const SyncToken& sync_token,
const Mailbox& mailbox) { … }
void TestSharedImageInterface::UpdateSharedImage(
const SyncToken& sync_token,
std::unique_ptr<gfx::GpuFence> acquire_fence,
const Mailbox& mailbox) { … }
scoped_refptr<ClientSharedImage>
TestSharedImageInterface::ImportSharedImage(
const ExportedSharedImage& exported_shared_image) { … }
void TestSharedImageInterface::DestroySharedImage(
const SyncToken& sync_token,
const Mailbox& mailbox) { … }
void TestSharedImageInterface::DestroySharedImage(
const SyncToken& sync_token,
scoped_refptr<ClientSharedImage> client_shared_image) { … }
SharedImageInterface::SwapChainSharedImages
TestSharedImageInterface::CreateSwapChain(viz::SharedImageFormat format,
const gfx::Size& size,
const gfx::ColorSpace& color_space,
GrSurfaceOrigin surface_origin,
SkAlphaType alpha_type,
gpu::SharedImageUsageSet usage) { … }
void TestSharedImageInterface::PresentSwapChain(
const SyncToken& sync_token,
const Mailbox& mailbox) { … }
#if BUILDFLAG(IS_FUCHSIA)
void TestSharedImageInterface::RegisterSysmemBufferCollection(
zx::eventpair service_handle,
zx::channel sysmem_token,
const viz::SharedImageFormat& format,
gfx::BufferUsage usage,
bool register_with_image_pipe) {
EXPECT_EQ(format, viz::MultiPlaneFormat::kNV12);
EXPECT_EQ(usage, gfx::BufferUsage::GPU_READ);
zx_koid_t id = base::GetKoid(service_handle).value();
std::unique_ptr<TestBufferCollection>& collection =
sysmem_buffer_collections_[id];
EXPECT_FALSE(collection);
collection = std::make_unique<TestBufferCollection>(std::move(service_handle),
std::move(sysmem_token));
}
#endif
SyncToken TestSharedImageInterface::GenVerifiedSyncToken() { … }
SyncToken TestSharedImageInterface::GenUnverifiedSyncToken() { … }
void TestSharedImageInterface::VerifySyncToken(SyncToken& sync_token) { … }
void TestSharedImageInterface::WaitSyncToken(const SyncToken& sync_token) { … }
void TestSharedImageInterface::Flush() { … }
scoped_refptr<gfx::NativePixmap> TestSharedImageInterface::GetNativePixmap(
const Mailbox& mailbox) { … }
bool TestSharedImageInterface::CheckSharedImageExists(
const Mailbox& mailbox) const { … }
const SharedImageCapabilities&
TestSharedImageInterface::GetCapabilities() { … }
void TestSharedImageInterface::SetCapabilities(
const SharedImageCapabilities& caps) { … }
void TestSharedImageInterface::InitializeSharedImageCapabilities() { … }
}