blob: d4d4ab8e9ab6d3919ca1fe114e2e5b1306915adb [file] [log] [blame]
// Copyright 2018 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_SIMPLE_CAMERA_SIMPLE_CAMERA_LIB_BUFFER_FENCE_H_
#define SRC_CAMERA_SIMPLE_CAMERA_SIMPLE_CAMERA_LIB_BUFFER_FENCE_H_
#include <lib/async/cpp/wait.h>
#include <lib/fit/function.h>
#include <lib/zx/event.h>
#include <src/lib/fxl/command_line.h>
#include <src/lib/fxl/log_settings_command_line.h>
#include <src/lib/fxl/logging.h>
#include <stdint.h>
#include <zircon/status.h>
namespace simple_camera {
class BufferFence;
using BufferCallback = fit::function<void(BufferFence*)>;
// BufferFence provides acquire and release fences
// which allow the locked or available status of the buffer to be
// signaled across processes. The fences follow the usage pattern
// described in image_pipe.fidl:
// The acquire fence signals the consumer that the writing is complete,
// and the release fence is signalled from the consumer that the
// frame is no longer needed for reading. These fences are indended for
// communication between only 2 processes; the fences are both reset upon
// receipt of the release fence signal.
// The state transitions of the buffer are thus:
// acquire fence | release fence | state
// 0 | 0 | Buffer is in writer control.
// | | The writer may be writing to the buffer.
// 1 | 0 | Buffer is done writing, signals the
// consumer.
// X | 1 | Consumer is done. The buffer calls
// OnReleaseFenceSignalled, and resets the
// fences.
// BufferFence also adds an index variable, which is used for external
// record-keeping. The index variable does not influence the internal
// workings of this class.
class BufferFence {
public:
~BufferFence();
void Reset(); // clear acquire and release fences
void Signal(); // set acquire fence
void DuplicateAcquireFence(zx::event* result) {
// TODO: remove write permissions
acquire_fence_.duplicate(ZX_RIGHT_SAME_RIGHTS, result);
}
void DuplicateReleaseFence(zx::event* result) {
release_fence_.duplicate(ZX_RIGHT_SAME_RIGHTS, result);
}
static std::unique_ptr<BufferFence> Create(uint32_t index);
// This function is called when the release fence is signalled
void OnReleaseFenceSignalled(async_dispatcher_t* dispatcher,
async::WaitBase* wait, zx_status_t status,
const zx_packet_signal* signal);
// Set a handler function that will be called whenever the release fence
// is signalled.
void SetReleaseFenceHandler(BufferCallback callback);
uint32_t index() { return index_; }
private:
uint32_t index_;
BufferCallback release_fence_callback_;
async::WaitMethod<BufferFence, &BufferFence::OnReleaseFenceSignalled>
release_fence_waiter_{this};
BufferFence();
zx::event acquire_fence_;
zx::event release_fence_;
};
} // namespace simple_camera
#endif // SRC_CAMERA_SIMPLE_CAMERA_SIMPLE_CAMERA_LIB_FENCED_BUFFER_H_