blob: 53745bff20f3b1989b2230de476e8fa7d2f32dd5 [file] [log] [blame]
// Copyright 2019 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 MSD_IMG_CONNECTION_H
#define MSD_IMG_CONNECTION_H
#include <memory>
#include <vector>
#include "include/fuchsia_communication.h"
#include "magma_util/macros.h"
#include "msd.h"
typedef struct _PVRSRV_DEVICE_NODE_ PVRSRV_DEVICE_NODE;
typedef struct _CONNECTION_DATA_ CONNECTION_DATA;
typedef struct PVRSRV_BRIDGE_PACKAGE_TAG PVRSRV_BRIDGE_PACKAGE;
class MsdImgBuffer;
class MsdImgSemaphore;
class MsdImgConnection : public msd_connection_t
{
public:
class Owner
{
public:
virtual PVRSRV_DEVICE_NODE* device_node() = 0;
};
// If the current thread is currently servicing a bridge request or other
// operation on a connection, this will return a pointer to that connection.
static MsdImgConnection* GetCurrentConnection();
virtual ~MsdImgConnection();
MsdImgConnection(Owner* owner, msd_client_id_t client_id);
void AssertValid()
{
// Use volatile to ensure the compiler won't optimize the check out if
// it realizes magic_ always == kMagic outside the constructor and
// destructor.
DASSERT(*const_cast<volatile int32_t*>(&magic_) == kMagic);
}
bool Init();
magma_status_t ExecuteCommandBuffer(magma_system_command_buffer* command_buffer,
magma_system_exec_resource* exec_resources,
msd_buffer_t** buffers,
msd_semaphore_t** signal_semaphores);
bool CopyFromUser(void* dest, const void* src, uint32_t size);
bool CopyToUser(void* dest, const void* src, uint32_t size);
static MsdImgConnection* Cast(msd_connection_t* msd_connection)
{
DASSERT(msd_connection);
DASSERT(msd_connection->magic_ == kMagic);
return static_cast<MsdImgConnection*>(msd_connection);
}
static MsdImgConnection* Cast(void* void_connection)
{
DASSERT(void_connection);
auto msd_connection = static_cast<MsdImgConnection*>(void_connection);
msd_connection->AssertValid();
return msd_connection;
}
Owner* owner() const { return owner_; }
msd_client_id_t client_id() const { return client_id_; }
// This is unchecked and comes from the client, so it should only be used
// for debug logging.
uint64_t current_client_thread_id() const { return current_client_thread_id_; }
char* client_name() { return client_name_; }
// Takes ownership of an additional buffer that was sent along with a
// command buffer. Once the buffer is taken, subsequent calls within the
// same execution of a bridge command will return null.
std::shared_ptr<MsdImgBuffer> TakeAdditionalBuffer();
// Takes ownership of an additional semaphore that was sent along with a
// command buffer. Once the semaphore is taken, subsequent calls within the
// same execution of a bridge command will return null.
std::shared_ptr<MsdImgSemaphore> TakeAdditionalSemaphore();
private:
friend class TestMsdImgConnection;
friend class TestOsFunc;
magma_status_t ProcessCommandBuffer(magma_system_command_buffer* command_buffer,
magma_system_exec_resource* exec_resources,
msd_buffer_t** buffers,
msd_semaphore_t** signal_semaphores,
PVRSRV_BRIDGE_PACKAGE* package_out,
volatile FuchsiaImgCommandPayload** payload_out,
std::vector<std::shared_ptr<MsdImgSemaphore>>* semaphores_out);
void CleanupAfterCommand(volatile FuchsiaImgCommandPayload* payload,
const std::vector<std::shared_ptr<MsdImgSemaphore>>& semaphores,
bool success);
static const uint32_t kMagic = 'icon';
Owner* owner_;
msd_client_id_t client_id_;
CONNECTION_DATA* connection_data_ = nullptr;
char client_name_[32];
uint64_t current_client_thread_id_;
// This member is only valid when ExecuteCommandBuffer is executing.
std::shared_ptr<MsdImgBuffer> payload_buffer_;
std::shared_ptr<MsdImgBuffer> additional_buffer_;
std::shared_ptr<MsdImgSemaphore> additional_semaphore_;
};
#endif // MSD_IMG_CONNECTION_H