summaryrefslogtreecommitdiff
path: root/src/ipa/rkisp1/module.h
AgeCommit message (Collapse)Author
2022-06-29ipa: libipa: Introduce a Module class templateLaurent Pinchart
libipa defines an abstract Algorithm class template that is specialized by IPA modules. IPA modules then instantiate and manage algorithms internally, without help from libipa. With ongoing work on tuning data support for the RkISP1, and future similar work for the IPU3, more code duplication for algorithms management is expected. To address this and share code between multiple IPA modules, introduce a new Module class template that will define and manage top-level concepts for the IPA module. The Module class template needs to be specialized with the same types as the Algorithm class. To avoid manual specialization of both classes, store the types in the Module class, and replace the template arguments of the Algorithm class with a single Module argument from which the other types are retrieved. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
/a> 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
 * Copyright (C) 2019, Google Inc.
 *
 * qt_event_dispatcher.cpp - qcam - Qt-based event dispatcher
 */

#include <chrono>
#include <iostream>

#include <QAbstractEventDispatcher>
#include <QCoreApplication>
#include <QSocketNotifier>
#include <QTimerEvent>

#include <libcamera/event_notifier.h>
#include <libcamera/timer.h>

#include "qt_event_dispatcher.h"

using namespace libcamera;

QtEventDispatcher::QtEventDispatcher()
{
}

QtEventDispatcher::~QtEventDispatcher()
{
	for (auto &it : notifiers_) {
		NotifierSet &set = it.second;
		delete set.read.qnotifier;
		delete set.write.qnotifier;
		delete set.exception.qnotifier;
	}
}

void QtEventDispatcher::registerEventNotifier(EventNotifier *notifier)
{
	NotifierSet &set = notifiers_[notifier->fd()];
	QSocketNotifier::Type qtype;
	void (QtEventDispatcher::*method)(int);
	NotifierPair *pair;

	switch (notifier->type()) {
	case EventNotifier::Read:
	default:
		qtype = QSocketNotifier::Read;
		method = &QtEventDispatcher::readNotifierActivated;
		pair = &set.read;
		break;

	case EventNotifier::Write:
		qtype = QSocketNotifier::Write;
		method = &QtEventDispatcher::writeNotifierActivated;
		pair = &set.write;
		break;

	case EventNotifier::Exception:
		qtype = QSocketNotifier::Exception;
		method = &QtEventDispatcher::exceptionNotifierActivated;
		pair = &set.exception;
		break;
	}

	QSocketNotifier *qnotifier = new QSocketNotifier(notifier->fd(), qtype);
	connect(qnotifier, &QSocketNotifier::activated, this, method);
	pair->notifier = notifier;
	pair->qnotifier = qnotifier;
}

void QtEventDispatcher::unregisterEventNotifier(EventNotifier *notifier)
{
	NotifierSet &set = notifiers_[notifier->fd()];
	NotifierPair *pair;

	switch (notifier->type()) {
	case EventNotifier::Read:
	default:
		pair = &set.read;
		break;

	case EventNotifier::Write:
		pair = &set.write;
		break;

	case EventNotifier::Exception:
		pair = &set.exception;
		break;
	}

	delete pair->qnotifier;
	pair->qnotifier = nullptr;
	pair->notifier = nullptr;
}

void QtEventDispatcher::readNotifierActivated(int socket)
{
	EventNotifier *notifier = notifiers_[socket].read.notifier;
	notifier->activated.emit(notifier);
}

void QtEventDispatcher::writeNotifierActivated(int socket)
{
	EventNotifier *notifier = notifiers_[socket].write.notifier;
	notifier->activated.emit(notifier);
}

void QtEventDispatcher::exceptionNotifierActivated(int socket)
{
	EventNotifier *notifier = notifiers_[socket].exception.notifier;
	notifier->activated.emit(notifier);
}

void QtEventDispatcher::registerTimer(Timer *timer)
{
	std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now();
	std::chrono::steady_clock::duration duration = timer->deadline() - now;
	std::chrono::milliseconds msec =
		std::chrono::duration_cast<std::chrono::milliseconds>(duration);
	int timerId = startTimer(msec.count());
	timers_[timerId] = timer;
	timerIds_[timer] = timerId;
}

void QtEventDispatcher::unregisterTimer(Timer *timer)
{
	auto it = timerIds_.find(timer);
	if (it == timerIds_.end())
		return;

	timers_.erase(it->second);
	killTimer(it->second);
	timerIds_.erase(it);
}

void QtEventDispatcher::timerEvent(QTimerEvent *event)
{
	Timer *timer = timers_[event->timerId()];
	timer->stop();
	timer->timeout.emit(timer);
}

void QtEventDispatcher::processEvents()
{
	std::cout << "QtEventDispatcher::processEvents() should not be called"
		  << std::endl;
}

void QtEventDispatcher::interrupt()
{
	QCoreApplication::eventDispatcher()->interrupt();
}