blob: f752f9e5f748594ccc7d82dd9e6b762d1553a1aa [file] [log] [blame] [edit]
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SRC_UI_SCENIC_LIB_FLATLAND_BUFFERS_UTIL_H_
#define SRC_UI_SCENIC_LIB_FLATLAND_BUFFERS_UTIL_H_
#include <fuchsia/sysmem2/cpp/fidl.h>
#include <lib/syslog/cpp/macros.h>
#include "src/ui/scenic/lib/flatland/buffers/buffer_collection.h"
namespace flatland {
fuchsia::sysmem2::BufferUsage get_none_usage();
struct SysmemTokens {
// Token for setting client side constraints.
fuchsia::sysmem2::BufferCollectionTokenSyncPtr local_token;
// Token for setting server side constraints.
fuchsia::sysmem2::BufferCollectionTokenSyncPtr dup_token;
static SysmemTokens Create(fuchsia::sysmem2::Allocator_Sync* sysmem_allocator) {
fuchsia::sysmem2::BufferCollectionTokenSyncPtr local_token;
fuchsia::sysmem2::AllocatorAllocateSharedCollectionRequest allocate_shared_request;
allocate_shared_request.set_token_request(local_token.NewRequest());
zx_status_t status =
sysmem_allocator->AllocateSharedCollection(std::move(allocate_shared_request));
FX_DCHECK(status == ZX_OK);
fuchsia::sysmem2::BufferCollectionTokenSyncPtr dup_token;
fuchsia::sysmem2::BufferCollectionTokenDuplicateRequest dup_request;
dup_request.set_rights_attenuation_mask(ZX_RIGHT_SAME_RIGHTS);
dup_request.set_token_request(dup_token.NewRequest());
status = local_token->Duplicate(std::move(dup_request));
FX_DCHECK(status == ZX_OK);
fuchsia::sysmem2::Node_Sync_Result sync_result;
status = local_token->Sync(&sync_result);
FX_DCHECK(status == ZX_OK);
FX_DCHECK(sync_result.is_response());
return {std::move(local_token), std::move(dup_token)};
}
};
// TODO(https://fxbug.dev/42132796): The default memory constraints set by Sysmem only allows using
// CPU domain for buffers with CPU usage, while Mali driver asks for only
// RAM and Inaccessible domains for buffer allocation, which caused failure in
// sysmem allocation. So here we add RAM domain support to clients in order
// to get buffer allocated correctly.
const std::pair<fuchsia::sysmem2::BufferUsage, fuchsia::sysmem2::BufferMemoryConstraints>
GetUsageAndMemoryConstraintsForCpuWriteOften();
// Sets the client constraints on a sysmem buffer collection, including the number of images,
// the dimensionality (width, height) of those images, the usage and memory constraints. This
// is a blocking function that will wait until the constraints have been fully set.
void SetClientConstraintsAndWaitForAllocated(
fuchsia::sysmem2::Allocator_Sync* sysmem_allocator,
fuchsia::sysmem2::BufferCollectionTokenSyncPtr token, uint32_t image_count = 1,
uint32_t width = 64, uint32_t height = 32,
fuchsia::sysmem2::BufferUsage usage = fidl::Clone(get_none_usage()),
const std::vector<fuchsia::images2::PixelFormatModifier>& additional_format_modifiers = {},
std::optional<fuchsia::sysmem2::BufferMemoryConstraints> memory_constraints = std::nullopt);
// Sets the constraints on a client buffer collection pointer and returns that pointer back to
// the caller, *without* waiting for the constraint setting to finish. It is up to the caller
// to wait until constraints are set.
fuchsia::sysmem2::BufferCollectionSyncPtr CreateBufferCollectionSyncPtrAndSetConstraints(
fuchsia::sysmem2::Allocator_Sync* sysmem_allocator,
fuchsia::sysmem2::BufferCollectionTokenSyncPtr token, uint32_t image_count = 1,
uint32_t width = 64, uint32_t height = 32,
fuchsia::sysmem2::BufferUsage usage = fidl::Clone(get_none_usage()),
fuchsia::images2::PixelFormat format = fuchsia::images2::PixelFormat::B8G8R8A8,
std::optional<fuchsia::sysmem2::BufferMemoryConstraints> memory_constraints = std::nullopt,
std::optional<fuchsia::images2::PixelFormatModifier> pixel_format_modifier = std::nullopt);
enum class HostPointerAccessMode : uint32_t {
kReadOnly = 0b01,
kWriteOnly = 0b10,
kReadWrite = 0b11,
};
// Maps a sysmem vmo's bytes into host memory that can be accessed via a callback function. The
// callback provides the caller with a raw pointer to the vmo memory as well as an int for the
// number of bytes. If an out of bounds vmo_idx is provided, the callback function will call the
// user callback with mapped_ptr equal to nullptr. Once the callback function returns, the host
// pointer is unmapped and so cannot continue to be used outside of the scope of the callback.
void MapHostPointer(const fuchsia::sysmem2::BufferCollectionInfo& collection_info, uint32_t vmo_idx,
HostPointerAccessMode host_pointer_access_mode,
std::function<void(uint8_t* mapped_ptr, uint32_t num_bytes)> callback);
// Maps a given vmo's bytes into host memory that can be accessed via a callback function. The
// callback provides the caller with a raw pointer to the vmo memory as well as an int for the
// number of bytes. Once the callback function returns, the host
// pointer is unmapped and so cannot continue to be used outside of the scope of the callback.
void MapHostPointer(const zx::vmo& vmo, HostPointerAccessMode host_pointer_access_mode,
std::function<void(uint8_t* mapped_ptr, uint32_t num_bytes)> callback,
uint64_t vmo_bytes = 0);
} // namespace flatland
#endif // SRC_UI_SCENIC_LIB_FLATLAND_BUFFERS_UTIL_H_