blob: 4ea562a079993575cbd76a2dccb55a6ef377f94b [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/hw_accel/gdc/gdc_task.h"
#include <lib/syslog/global.h>
#include <stdint.h>
#include <zircon/types.h>
#include <memory>
#include <ddk/debug.h>
constexpr auto kTag = "gdc";
namespace gdc {
zx_status_t GdcTask::PinConfigVmos(const gdc_config_info* config_vmo_list, size_t config_vmos_count,
const zx::bti& bti) {
pinned_config_vmos_ =
fbl::Array<fzl::PinnedVmo>(new fzl::PinnedVmo[config_vmos_count], config_vmos_count);
for (uint32_t i = 0; i < config_vmos_count; i++) {
zx::vmo vmo(config_vmo_list[i].config_vmo);
if (!vmo.is_valid()) {
return ZX_ERR_INVALID_ARGS;
}
uint64_t size;
auto status = vmo.get_size(&size);
if (status != ZX_OK) {
FX_LOG(ERROR, kTag, "Unable to get VMO size");
return status;
}
zx::vmo contig_vmo;
status = zx::vmo::create_contiguous(bti, size, 0, &contig_vmo);
if (status != ZX_OK) {
FX_LOG(ERROR, kTag, "Unable to get create contiguous VMO");
return status;
}
fzl::VmoMapper mapped_buffer_vmo;
status = mapped_buffer_vmo.Map(vmo, 0, 0, ZX_VM_PERM_READ);
if (status != ZX_OK) {
FX_LOG(ERROR, kTag, "Unable to get map VMO");
return status;
}
fzl::VmoMapper mapped_buffer_contig_vmo;
status = mapped_buffer_contig_vmo.Map(contig_vmo, 0, 0, ZX_VM_PERM_READ | ZX_VM_PERM_WRITE);
if (status != ZX_OK) {
FX_LOG(ERROR, kTag, "Unable to get map contig VMO");
return status;
}
memcpy(mapped_buffer_contig_vmo.start(), mapped_buffer_vmo.start(), size);
// Clean and invalidate the contiguous VMO.
status = contig_vmo.op_range(ZX_VMO_OP_CACHE_CLEAN, 0, size, nullptr, 0);
if (status != ZX_OK) {
FX_LOG(ERROR, kTag, "Unable to clean and invalidate the cache");
return status;
}
status = pinned_config_vmos_[i].Pin(contig_vmo, bti, ZX_BTI_CONTIGUOUS | ZX_VM_PERM_READ);
if (status != ZX_OK) {
FX_LOG(ERROR, kTag, "Failed to pin config VMO");
return status;
}
if (pinned_config_vmos_[i].region_count() != 1) {
FX_LOG(ERROR, kTag, "Buffer is not contiguous");
return ZX_ERR_NO_MEMORY;
}
gdc_config_info config_info;
config_info.config_vmo = std::move(contig_vmo.release());
config_info.size = config_vmo_list[i].size;
config_contig_vmos_.push_back(std::move(config_info));
// Release the vmos so that the handle doesn't get closed
__UNUSED zx_handle_t handle = vmo.release();
}
return ZX_OK;
}
zx_status_t GdcTask::Init(const buffer_collection_info_2_t* input_buffer_collection,
const buffer_collection_info_2_t* output_buffer_collection,
const image_format_2_t* input_image_format,
const image_format_2_t* output_image_format_table_list,
size_t output_image_format_table_count,
uint32_t output_image_format_index,
const gdc_config_info* config_vmo_list, size_t config_vmos_count,
const hw_accel_frame_callback_t* frame_callback,
const hw_accel_res_change_callback_t* res_callback,
const hw_accel_remove_task_callback_t* remove_task_callback,
const zx::bti& bti) {
if (frame_callback == nullptr || res_callback == nullptr || config_vmo_list == nullptr ||
remove_task_callback == nullptr || config_vmos_count == 0 ||
config_vmos_count != output_image_format_table_count ||
(output_image_format_table_count < 1) ||
(output_image_format_index >= output_image_format_table_count)) {
return ZX_ERR_INVALID_ARGS;
}
zx_status_t status = PinConfigVmos(config_vmo_list, config_vmos_count, bti);
if (status != ZX_OK) {
FX_LOG(ERROR, kTag, "PinConfigVmo Failed");
return status;
}
status = InitBuffers(input_buffer_collection, output_buffer_collection, input_image_format, 1, 0,
output_image_format_table_list, output_image_format_table_count,
output_image_format_index, bti, frame_callback, res_callback,
remove_task_callback);
if (status != ZX_OK) {
FX_LOG(ERROR, kTag, "InitBuffers Failed");
return status;
}
return status;
}
} // namespace gdc