blob: 6e3b3f53f6192456e5af5cc0b2d5ec7c0a028ec0 [file] [log] [blame]
// Copyright 2017 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 GARNET_LIB_MAGMA_SRC_DISPLAY_PIPE_CLIENT_BUFFER_H_
#define GARNET_LIB_MAGMA_SRC_DISPLAY_PIPE_CLIENT_BUFFER_H_
#include <stdint.h>
#include <zx/event.h>
#include <zx/vmo.h>
#include "lib/fsl/tasks/message_loop.h"
#include "lib/fxl/command_line.h"
#include "lib/fxl/log_settings_command_line.h"
#include "lib/fxl/logging.h"
#include "zircon/status.h"
#include <fbl/function.h>
#include <async/cpp/auto_wait.h>
class Buffer;
using BufferCallback = fbl::Function<void(Buffer *)>;
struct BufferLayout {
zx::vmo buffer_vmo;
std::vector<uint64_t> buffer_sizes;
std::vector<uint64_t> buffer_offsets;
};
class Buffer {
enum class BufferState {
kInvalid = 0,
kAvailable,
kWriteLocked,
kReadLocked
};
public:
~Buffer();
// Assumes that the buffer is set up as an ARGB image,
// with 4 bytes per pixel. Fills the entire size of the buffer
// with a set color with the red, green and blue channels
// indicated by the r, g and b arguments.
void FillARGB(uint8_t r, uint8_t g, uint8_t b);
void ConvertToRGBA(Buffer *b, int gamma = 0);
void ConvertToBgraAndMirror(Buffer *b, uint32_t width, int gamma = 0);
void Reset(); // clear acquire and release fences
void Signal(); // set acquire fence
const zx::event& acqure_fence() { return acquire_fence_; }
const zx::event& release_fence() { return release_fence_; }
void dupAcquireFence(zx::event *result) {
// TODO: remove write permissions
acquire_fence_.duplicate(ZX_RIGHT_SAME_RIGHTS, result);
}
void dupReleaseFence(zx::event *result) {
release_fence_.duplicate(ZX_RIGHT_SAME_RIGHTS, result);
}
void ReplaceReleaseFence(const zx::event &new_event) {
release_fence_.reset();
new_event.duplicate(ZX_RIGHT_SAME_RIGHTS, &release_fence_);
// new_event.replace(ZX_RIGHT_SAME_RIGHTS, &release_fence_);
}
void dupVmo(zx::vmo *result) {
vmo_.duplicate(ZX_RIGHT_SAME_RIGHTS & ~ZX_RIGHT_WRITE, result);
}
static Buffer *NewBuffer(uint64_t buffer_size, const zx::vmo &main_buffer, uint64_t offset, uint32_t index);
// Writes the contents of the buffer to a file, no header
zx_status_t SaveToFile(const char *filename);
// returns true if the buffer is neither read locked or write locked.
bool IsAvailable() {
return state_ == BufferState::kAvailable;
}
// This function is called when the release fence is signalled
async_wait_result_t OnReleaseFenceSignalled(async_t* async, 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);
void SetReleaseFenceHandler(BufferCallback callback);
uint32_t index() { return index_; }
uint64_t vmo_offset() { return vmo_offset_; }
uint64_t size() { return size_; }
private:
uint32_t index_;
BufferCallback release_fence_callback_;
async::AutoWait release_fence_waiter_;
uint32_t *pixels_;
Buffer() : release_fence_waiter_(fsl::MessageLoop::GetCurrent()->async()) {};
zx::vmo vmo_;
uint64_t vmo_offset_;
uint64_t size_;
BufferState state_ = BufferState::kInvalid;
zx::event acquire_fence_;
zx::event release_fence_;
};
#endif // GARNET_LIB_MAGMA_SRC_DISPLAY_PIPE_CLIENT_BUFFER_H_