| // 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_ |