blob: dab9f3e2648352e118eda4561fb2e3202a9a6000 [file] [log] [blame]
// Copyright 2024 The Pigweed Authors
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
#pragma once
#include <array>
#include <cstdint>
#include "pw_containers/vector.h"
#include "pw_framebuffer/framebuffer.h"
#include "pw_geometry/size.h"
#include "pw_status/status.h"
#include "pw_sync/counting_semaphore.h"
/// @defgroup pw_framebuffer_pool
namespace pw::framebuffer_pool {
/// @ingroup pw_framebuffer_pool
///
/// FramebufferPool manages a collection of (one or more) framebuffers.
/// It provides a mechanism to retrieve a buffer from the pool for use, and
/// for returning that buffer back to the pool.
class FramebufferPool {
public:
using BufferArray = pw::Vector<void*>;
/// Constructor parameters.
struct Config {
/// Address of each buffer in this pool.
const BufferArray& fb_addr;
/// Width/height of each buffer.
pw::geometry::Size<uint16_t> dimensions;
/// Row bytes of each buffer.
uint16_t row_bytes;
/// Shared pixel format.
pw::framebuffer::PixelFormat pixel_format;
};
FramebufferPool(const Config& config);
virtual ~FramebufferPool();
/// Return the framebuffer addresses for initialization purposes only.
/// Some drivers require these during initialization of their subsystems.
/// Do not use this as a means to retrieve the address of a framebuffer.
/// Always use GetFramebuffer if a new buffer is needed.
const BufferArray& GetBuffersForInit() const { return buffer_addresses_; }
/// Return the row bytes for each framebuffer in this pool.
uint16_t row_bytes() const { return row_bytes_; }
/// Return the dimensions (width/height) for each framebuffer in this pool.
pw::geometry::Size<uint16_t> dimensions() const { return buffer_dimensions_; }
/// Return the pixel format for each framebuffer in this pool.
pw::framebuffer::PixelFormat pixel_format() const { return pixel_format_; }
/// Return a framebuffer to the caller for use. This call WILL BLOCK until a
/// framebuffer is returned for use. Framebuffers *must* be returned to this
/// pool by a corresponding call to ReleaseFramebuffer. This function will
/// only return a valid framebuffers.
///
/// This call is thread-safe, but not interrupt safe.
virtual pw::framebuffer::Framebuffer GetFramebuffer();
/// Return the framebuffer to the pool available for use by the next call to
/// GetFramebuffer.
///
/// This may be called on another thread or during an interrupt.
virtual Status ReleaseFramebuffer(pw::framebuffer::Framebuffer framebuffer);
private:
pw::sync::CountingSemaphore framebuffer_semaphore_;
/// Address of each pixel buffer.
const BufferArray& buffer_addresses_;
/// Width/height of all buffers
pw::geometry::Size<uint16_t> buffer_dimensions_;
/// All row bytes are the same.
uint16_t row_bytes_;
/// Shared pixel format.
pw::framebuffer::PixelFormat pixel_format_;
volatile size_t next_fb_idx_;
};
} // namespace pw::framebuffer_pool