@@ -59,7 +59,6 @@ public:
void stop(Camera *camera);
bool hasPendingRequests(const Camera *camera) const;
- void registerRequest(Request *request);
void queueRequest(Request *request);
static bool completeBuffer(Request *request, FrameBuffer *buffer)
@@ -7,19 +7,13 @@
#pragma once
-#include <chrono>
-#include <map>
-#include <memory>
#include <stdint.h>
#include <unordered_set>
#include <libcamera/base/event_notifier.h>
-#include <libcamera/base/timer.h>
#include <libcamera/request.h>
-using namespace std::chrono_literals;
-
namespace libcamera {
class Camera;
@@ -43,26 +37,17 @@ public:
void cancel();
void reset();
- void prepare(std::chrono::milliseconds timeout = 0ms);
- Signal<> prepared;
-
private:
friend class PipelineHandler;
friend std::ostream &operator<<(std::ostream &out, const Request &r);
void doCancelRequest();
- void emitPrepareCompleted();
- void notifierActivated(FrameBuffer *buffer);
- void timeout();
Camera *camera_;
bool cancelled_;
uint32_t sequence_ = 0;
- bool prepared_ = false;
std::unordered_set<FrameBuffer *> pending_;
- std::map<FrameBuffer *, EventNotifier> notifiers_;
- std::unique_ptr<Timer> timer_;
ControlList metadata_;
};
@@ -1294,12 +1294,7 @@ std::unique_ptr<Request> Camera::createRequest(uint64_t cookie)
if (ret < 0)
return nullptr;
- std::unique_ptr<Request> request = std::make_unique<Request>(this, cookie);
-
- /* Associate the request with the pipeline handler. */
- d->pipe_->registerRequest(request.get());
-
- return request;
+ return std::make_unique<Request>(this, cookie);
}
/**
@@ -28,8 +28,6 @@ namespace libcamera {
* the Fence to be signalled before allowing the camera device to actually
* access the memory area described by the FrameBuffer.
*
- * \sa Request::addBuffer()
- *
* By using a fence, applications can then synchronize between frame buffer
* consumers and producers, as for example a display device and a camera, to
* guarantee that a new data transfers only happen once the existing frames have
@@ -68,9 +66,6 @@ namespace libcamera {
*
* A failure in waiting for a Fence to complete will result in the Request to
* complete in failed state.
- *
- * \sa Request::prepare()
- * \sa PipelineHandler::doQueueRequests()
*/
/**
@@ -191,9 +191,7 @@ FrameBuffer::Private::~Private()
*
* If buffer with a Fence completes with errors due to a failure in handling
* the fence, applications are responsible for releasing the Fence before
- * calling Request::addBuffer() again.
- *
- * \sa Request::addBuffer()
+ * reusing the buffer.
*
* \return A const pointer to the Fence if any, nullptr otherwise
*/
@@ -203,15 +201,13 @@ FrameBuffer::Private::~Private()
* \brief Move a \a fence in this buffer
* \param[in] fence The Fence
*
- * This function associates a Fence with this Framebuffer. The intended caller
- * is the Request::addBuffer() function.
+ * This function associates a Fence with this Framebuffer. It is only intended
+ * to be called by the libcamera core.
*
* Once a FrameBuffer is associated with a Fence, the FrameBuffer will only be
* made available to the hardware device once the Fence has been correctly
* signalled.
*
- * \sa Request::prepare()
- *
* If the FrameBuffer completes successfully the core releases the Fence and the
* Buffer can be reused immediately. If handling of the Fence fails during the
* request preparation, the Fence is not released and is left in the
@@ -7,7 +7,6 @@
#include "libcamera/internal/pipeline_handler.h"
-#include <chrono>
#include <sys/stat.h>
#include <sys/sysmacros.h>
@@ -443,25 +442,6 @@ bool PipelineHandler::hasPendingRequests(const Camera *camera) const
return !camera->_d()->queuedRequests_.empty();
}
-/**
- * \fn PipelineHandler::registerRequest()
- * \brief Register a request for use by the pipeline handler
- * \param[in] request The request to register
- *
- * This function is called when the request is created, and allows the pipeline
- * handler to perform any one-time initialization it requries for the request.
- */
-void PipelineHandler::registerRequest(Request *request)
-{
- /*
- * Connect the request prepared signal to notify the pipeline handler
- * when a request is ready to be processed.
- */
- request->_d()->prepared.connect(this, [this, request]() {
- doQueueRequests(request->_d()->camera());
- });
-}
-
/**
* \fn PipelineHandler::queueRequest()
* \brief Queue a request
@@ -493,7 +473,7 @@ void PipelineHandler::queueRequest(Request *request)
Camera::Private *data = camera->_d();
data->waitingRequests_.push(request);
- request->_d()->prepare(300ms);
+ doQueueRequests(camera);
}
/**
@@ -533,8 +513,6 @@ void PipelineHandler::doQueueRequests(Camera *camera)
break;
Request *request = data->waitingRequests_.front();
- if (!request->_d()->prepared_)
- break;
/*
* Pop the request first, in case doQueueRequests() is called
@@ -7,7 +7,6 @@
#include "libcamera/internal/request.h"
-#include <map>
#include <sstream>
#include <libcamera/base/log.h>
@@ -155,8 +154,6 @@ void Request::Private::doCancelRequest()
cancelled_ = true;
pending_.clear();
- notifiers_.clear();
- timer_.reset();
}
/**
@@ -187,135 +184,7 @@ void Request::Private::reset()
{
sequence_ = 0;
cancelled_ = false;
- prepared_ = false;
pending_.clear();
- notifiers_.clear();
- timer_.reset();
-}
-
-/*
- * Helper function to save some lines of code and make sure prepared_ is set
- * to true before emitting the signal.
- */
-void Request::Private::emitPrepareCompleted()
-{
- prepared_ = true;
- prepared.emit();
-}
-
-/**
- * \brief Prepare the Request to be queued to the device
- * \param[in] timeout Optional expiration timeout
- *
- * Prepare a Request to be queued to the hardware device by ensuring it is
- * ready for the incoming memory transfers.
- *
- * This currently means waiting on each frame buffer acquire fence to be
- * signalled. An optional expiration timeout can be specified. If not all the
- * fences have been signalled correctly before the timeout expires the Request
- * is cancelled.
- *
- * The function immediately emits the prepared signal if all the prepare
- * operations have been completed synchronously. If instead the prepare
- * operations require to wait the completion of asynchronous events, such as
- * fences notifications or timer expiration, the prepared signal is emitted upon
- * the asynchronous event completion.
- *
- * As we currently only handle fences, the function emits the prepared signal
- * immediately if there are no fences to wait on. Otherwise the prepared signal
- * is emitted when all fences have been signalled or the optional timeout has
- * expired.
- *
- * If not all the fences have been correctly signalled or the optional timeout
- * has expired the Request will be cancelled and the Request::prepared signal
- * emitted.
- *
- * The intended user of this function is the PipelineHandler base class, which
- * 'prepares' a Request before queuing it to the hardware device.
- */
-void Request::Private::prepare(std::chrono::milliseconds timeout)
-{
- /* Create and connect one notifier for each synchronization fence. */
- for (FrameBuffer *buffer : pending_) {
- const Fence *fence = buffer->_d()->fence();
- if (!fence)
- continue;
-
- auto [it, inserted] = notifiers_.try_emplace(buffer, fence->fd().get(), EventNotifier::Type::Read);
- ASSERT(inserted);
-
- it->second.activated.connect(this, [this, buffer] {
- notifierActivated(buffer);
- });
- }
-
- if (notifiers_.empty()) {
- emitPrepareCompleted();
- return;
- }
-
- /*
- * In case a timeout is specified, create a timer and set it up.
- *
- * The timer must be created here instead of in the Request constructor,
- * in order to be bound to the pipeline handler thread.
- */
- if (timeout != 0ms) {
- timer_ = std::make_unique<Timer>();
- timer_->timeout.connect(this, &Request::Private::timeout);
- timer_->start(timeout);
- }
-}
-
-/**
- * \var Request::Private::prepared
- * \brief Request preparation completed Signal
- *
- * The signal is emitted once the request preparation has completed and is ready
- * to be queued. The Request might complete with errors in which case it is
- * cancelled.
- *
- * The intended slot for this signal is the PipelineHandler::doQueueRequests()
- * function which queues Request after they have been prepared or cancel them
- * if they have failed preparing.
- */
-
-void Request::Private::notifierActivated(FrameBuffer *buffer)
-{
- /* Close the fence if successfully signalled. */
- ASSERT(buffer);
- buffer->releaseFence();
-
- /* Remove the entry from the map and check if other fences are pending. */
- auto it = notifiers_.find(buffer);
- ASSERT(it != notifiers_.end());
- notifiers_.erase(it);
-
- Request *request = _o<Request>();
- LOG(Request, Debug)
- << "Request " << request->cookie() << " buffer " << buffer
- << " fence signalled";
-
- if (!notifiers_.empty())
- return;
-
- /* All fences completed, delete the timer and emit the prepared signal. */
- timer_.reset();
- emitPrepareCompleted();
-}
-
-void Request::Private::timeout()
-{
- /* A timeout can only happen if there are fences not yet signalled. */
- ASSERT(!notifiers_.empty());
- notifiers_.clear();
-
- Request *request = _o<Request>();
- LOG(Request, Debug) << "Request prepare timeout: " << request->cookie();
-
- cancel();
-
- emitPrepareCompleted();
}
#endif /* __DOXYGEN_PUBLIC__ */
With the split of buffers and requests, fences will need to be handled outside of requests. So remove the current fence support, all the miscellaneous things related to it: * Request::{prepared,prepared_} * PipelineHandler::registerRequest() Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com> --- include/libcamera/internal/pipeline_handler.h | 1 - include/libcamera/internal/request.h | 15 -- src/libcamera/camera.cpp | 7 +- src/libcamera/fence.cpp | 5 - src/libcamera/framebuffer.cpp | 10 +- src/libcamera/pipeline_handler.cpp | 24 +--- src/libcamera/request.cpp | 131 ------------------ 7 files changed, 5 insertions(+), 188 deletions(-)