blob: 15179f4f342b3cafc862e04a887f65d8ea8b611c [file] [log] [blame]
// 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_CAMERA_DRIVERS_CONTROLLER_TEST_FAKE_GE2D_H_
#define SRC_CAMERA_DRIVERS_CONTROLLER_TEST_FAKE_GE2D_H_
#include <fuchsia/hardware/ge2d/cpp/banjo.h>
#include <lib/fake_ddk/fake_ddk.h>
#include <lib/sys/cpp/component_context.h>
class FakeGe2d;
class FakeGe2d {
public:
static constexpr int64_t kFrameDelayClocks = 100;
FakeGe2d() {
ge2d_protocol_ops_.init_task_resize = Ge2dInitTaskResize;
ge2d_protocol_ops_.init_task_water_mark = Ge2dInitTaskWaterMark;
ge2d_protocol_ops_.init_task_in_place_water_mark = Ge2dInitTaskInPlaceWaterMark;
ge2d_protocol_ops_.process_frame = Ge2dProcessFrame;
ge2d_protocol_ops_.remove_task = Ge2dRemoveTask;
ge2d_protocol_ops_.release_frame = Ge2dReleaseFrame;
ge2d_protocol_ops_.set_output_resolution = Ge2dSetOutputResolution;
ge2d_protocol_ops_.set_input_and_output_resolution = Ge2dSetInputAndOutputResolution;
ge2d_protocol_ops_.set_crop_rect = Ge2dSetCropRect;
ge2d_protocol_.ctx = this;
ge2d_protocol_.ops = &ge2d_protocol_ops_;
}
ddk::Ge2dProtocolClient client() { return ddk::Ge2dProtocolClient(&ge2d_protocol_); }
fake_ddk::ProtocolEntry ProtocolEntry() const {
return {ZX_PROTOCOL_GE2D, *reinterpret_cast<const fake_ddk::Protocol*>(&ge2d_protocol_)};
}
// ZX_PROTOCOL_GE2DC (Refer to ge2d.banjo for documentation).
zx_status_t Ge2dInitTaskResize(const buffer_collection_info_2_t* /*input_buffer_collection*/,
const buffer_collection_info_2_t* /*output_buffer_collection*/,
const resize_info_t* /*info*/,
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 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,
uint32_t* /*out_task_index*/) {
remove_task_callback_ = remove_task_callback;
frame_callback_ = frame_callback;
res_change_callback_ = res_callback;
image_format_index_ = output_image_format_index;
return ZX_OK;
}
zx_status_t Ge2dInitTaskInPlaceWaterMark(
const buffer_collection_info_2_t* /*output_buffer_collection*/,
const water_mark_info_t* /*info_list*/, size_t /*info_count*/,
const image_format_2_t* /*image_format_table_list*/, size_t /*image_format_table_count*/,
uint32_t image_format_index, 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, uint32_t* /*out_task_index*/) {
remove_task_callback_ = remove_task_callback;
frame_callback_ = frame_callback;
res_change_callback_ = res_callback;
image_format_index_ = image_format_index;
return ZX_OK;
}
zx_status_t Ge2dInitTaskWaterMark(const buffer_collection_info_2_t* /*input_buffer_collection*/,
const buffer_collection_info_2_t* /*output_buffer_collection*/,
const water_mark_info_t* /*info_list*/, size_t /*info_count*/,
const image_format_2_t* /*image_format_table_list*/,
size_t /*image_format_table_count*/,
uint32_t image_format_index,
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,
uint32_t* /*out_task_index*/) {
remove_task_callback_ = remove_task_callback;
frame_callback_ = frame_callback;
res_change_callback_ = res_callback;
image_format_index_ = image_format_index;
return ZX_OK;
}
zx_status_t Ge2dProcessFrame(uint32_t /*task_index*/, uint32_t input_buffer_index,
uint64_t capture_timestamp) {
frame_available_info info = {
.frame_status = FRAME_STATUS_OK,
.buffer_id = input_buffer_index,
.metadata.input_buffer_index = input_buffer_index,
.metadata.image_format_index = image_format_index_,
.metadata.timestamp = capture_timestamp + kFrameDelayClocks,
.metadata.capture_timestamp = capture_timestamp,
};
frame_callback_->frame_ready(frame_callback_->ctx, &info);
return ZX_OK;
}
void Ge2dRemoveTask(uint32_t task_index) {}
void Ge2dReleaseFrame(uint32_t task_index, uint32_t buffer_index) {}
zx_status_t Ge2dSetInputAndOutputResolution(uint32_t /*task_index*/,
uint32_t new_image_format_index) {
image_format_index_ = new_image_format_index;
image_format_index_ = new_image_format_index;
frame_available_info info = {
.frame_status = FRAME_STATUS_OK,
.buffer_id = 0,
.metadata.input_buffer_index = 0,
.metadata.image_format_index = image_format_index_,
};
res_change_callback_->frame_resolution_changed(res_change_callback_->ctx, &info);
return ZX_OK;
}
zx_status_t Ge2dSetOutputResolution(uint32_t /*task_index*/,
uint32_t new_output_image_format_index) {
image_format_index_ = new_output_image_format_index;
image_format_index_ = new_output_image_format_index;
frame_available_info info = {
.frame_status = FRAME_STATUS_OK,
.buffer_id = 0,
.metadata.input_buffer_index = 0,
.metadata.image_format_index = image_format_index_,
};
res_change_callback_->frame_resolution_changed(res_change_callback_->ctx, &info);
return ZX_OK;
}
void Ge2dSetCropRect(uint32_t task_index, const rect_t* crop) { crop_rect_ = *crop; }
std::optional<rect_t>& crop_rect() { return crop_rect_; }
private:
static zx_status_t Ge2dInitTaskResize(
void* ctx, const buffer_collection_info_2_t* input_buffer_collection,
const buffer_collection_info_2_t* output_buffer_collection, const resize_info_t* info,
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 hw_accel_frame_callback_t* frame_callback,
const hw_accel_res_change_callback_t* res_callback,
const hw_accel_remove_task_callback_t* task_remove_callback, uint32_t* out_task_index) {
return static_cast<FakeGe2d*>(ctx)->Ge2dInitTaskResize(
input_buffer_collection, output_buffer_collection, info, input_image_format,
output_image_format_table_list, output_image_format_table_count, output_image_format_index,
frame_callback, res_callback, task_remove_callback, out_task_index);
}
static zx_status_t Ge2dInitTaskWaterMark(
void* ctx, const buffer_collection_info_2_t* input_buffer_collection,
const buffer_collection_info_2_t* output_buffer_collection,
const water_mark_info_t* info_list, size_t info_count,
const image_format_2_t* image_format_table_list, size_t image_format_table_count,
uint32_t image_format_index, const hw_accel_frame_callback_t* frame_callback,
const hw_accel_res_change_callback_t* res_callback,
const hw_accel_remove_task_callback_t* task_remove_callback, uint32_t* out_task_index) {
return static_cast<FakeGe2d*>(ctx)->Ge2dInitTaskWaterMark(
input_buffer_collection, output_buffer_collection, info_list, info_count,
image_format_table_list, image_format_table_count, image_format_index, frame_callback,
res_callback, task_remove_callback, out_task_index);
}
static zx_status_t Ge2dInitTaskInPlaceWaterMark(
void* ctx, const buffer_collection_info_2_t* buffer_collection,
const water_mark_info_t* info_list, size_t info_count,
const image_format_2_t* image_format_table_list, size_t image_format_table_count,
uint32_t image_format_index, const hw_accel_frame_callback_t* frame_callback,
const hw_accel_res_change_callback_t* res_callback,
const hw_accel_remove_task_callback_t* task_remove_callback, uint32_t* out_task_index) {
return static_cast<FakeGe2d*>(ctx)->Ge2dInitTaskInPlaceWaterMark(
buffer_collection, info_list, info_count, image_format_table_list, image_format_table_count,
image_format_index, frame_callback, res_callback, task_remove_callback, out_task_index);
}
static zx_status_t Ge2dProcessFrame(void* ctx, uint32_t task_index, uint32_t input_buffer_index,
uint64_t capture_timestamp) {
return static_cast<FakeGe2d*>(ctx)->Ge2dProcessFrame(task_index, input_buffer_index,
capture_timestamp);
}
static void Ge2dRemoveTask(void* ctx, uint32_t task_index) {
return static_cast<FakeGe2d*>(ctx)->Ge2dRemoveTask(task_index);
}
static void Ge2dReleaseFrame(void* ctx, uint32_t task_index, uint32_t buffer_index) {
return static_cast<FakeGe2d*>(ctx)->Ge2dReleaseFrame(task_index, buffer_index);
}
static zx_status_t Ge2dSetInputAndOutputResolution(void* ctx, uint32_t task_index,
uint32_t new_image_format_index) {
return static_cast<FakeGe2d*>(ctx)->Ge2dSetInputAndOutputResolution(task_index,
new_image_format_index);
}
static zx_status_t Ge2dSetOutputResolution(void* ctx, uint32_t task_index,
uint32_t new_output_image_format_index) {
return static_cast<FakeGe2d*>(ctx)->Ge2dSetOutputResolution(task_index,
new_output_image_format_index);
}
static void Ge2dSetCropRect(void* ctx, uint32_t task_index, const rect_t* crop) {
return static_cast<FakeGe2d*>(ctx)->Ge2dSetCropRect(task_index, crop);
}
ge2d_protocol_t ge2d_protocol_ = {};
ge2d_protocol_ops_t ge2d_protocol_ops_ = {};
const hw_accel_remove_task_callback_t* remove_task_callback_;
const hw_accel_frame_callback_t* frame_callback_;
const hw_accel_res_change_callback_t* res_change_callback_;
uint32_t image_format_index_ = -1;
std::optional<rect_t> crop_rect_;
};
#endif // SRC_CAMERA_DRIVERS_CONTROLLER_TEST_FAKE_GE2D_H_