blob: 74679ed5e1b481b73c35512c932bcb09d36b4a20 [file] [log] [blame]
// Copyright 2019 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.
#include "src/camera/drivers/controller/graph_utils.h"
#include <lib/fpromise/result.h>
#include <lib/syslog/cpp/macros.h>
#include <zircon/errors.h>
#include <zircon/types.h>
#include "src/camera/drivers/controller/configs/internal_config.h"
#include "src/lib/fsl/handles/object_info.h"
namespace camera {
constexpr auto kTag = "camera_controller_graph_helper";
const InternalConfigNode* GetNextNodeInPipeline(const fuchsia::camera2::CameraStreamType& stream,
const InternalConfigNode& node) {
for (const auto& child_node : node.child_nodes) {
for (uint32_t i = 0; i < child_node.supported_streams.size(); i++) {
if (child_node.supported_streams[i].type == stream) {
return &child_node;
}
}
}
return nullptr;
}
fpromise::result<BufferCollection, zx_status_t> GetBuffers(
const ControllerMemoryAllocator& memory_allocator, const InternalConfigNode& producer,
StreamCreationData* info, const std::string& buffer_tag) {
BufferCollection collection;
const auto* consumer = GetNextNodeInPipeline(info->stream_type(), producer);
auto current_producer = &producer;
if (!consumer) {
FX_LOGST(ERROR, kTag) << "Failed to get next node";
return fpromise::error(ZX_ERR_INTERNAL);
}
// The controller might need to allocate memory using sysmem.
// Populate the constraints.
std::vector<fuchsia::sysmem::BufferCollectionConstraints> constraints;
constraints.push_back(producer.output_constraints);
while (consumer->in_place) {
if (current_producer->child_nodes.size() != 1) {
FX_LOGST(ERROR, kTag)
<< "Invalid configuration. A buffer is shared with a node which does in place operations";
return fpromise::error(ZX_ERR_BAD_STATE);
}
constraints.push_back(consumer->input_constraints);
current_producer = consumer;
consumer = &consumer->child_nodes[0];
}
for (const auto& node : current_producer->child_nodes) {
if (node.type != kOutputStream) {
constraints.push_back(node.input_constraints);
}
}
auto status = memory_allocator.AllocateSharedMemory(constraints, collection, buffer_tag);
if (status != ZX_OK) {
FX_PLOGS(ERROR, status) << "Failed to allocate shared memory";
return fpromise::error(status);
}
FX_LOGST(DEBUG, kTag) << "Allocated " << collection.buffers.buffer_count << " buffers for "
<< buffer_tag;
return fpromise::ok(std::move(collection));
}
} // namespace camera