blob: b6bfb5c116acc34ba51d1e02ff2bfe17b88a3812 [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <stddef.h>
#include <stdint.h>
#include <memory>
#include "base/callback.h"
#include "base/macros.h"
#include "gpu/command_buffer/common/command_buffer.h"
#include "gpu/command_buffer/common/command_buffer_shared.h"
#include "gpu/command_buffer/service/async_api_interface.h"
namespace gpu {
class TransferBufferManager;
class GPU_EXPORT CommandBufferServiceBase {
virtual ~CommandBufferServiceBase() = default;
// Gets the current state of the service.
virtual CommandBuffer::State GetState() = 0;
// Set the release count for the last fence sync seen in the command stream.
virtual void SetReleaseCount(uint64_t release_count) = 0;
// Get the transfer buffer associated with an ID. Returns a null buffer for
// ID 0.
virtual scoped_refptr<gpu::Buffer> GetTransferBuffer(int32_t id) = 0;
// Allows the reader to update the current token value.
virtual void SetToken(int32_t token) = 0;
// Allows the reader to set the current parse error.
virtual void SetParseError(error::Error) = 0;
// Allows the reader to set the current context lost reason.
// NOTE: if calling this in conjunction with SetParseError,
// call this first.
virtual void SetContextLostReason(error::ContextLostReason) = 0;
class GPU_EXPORT CommandBufferServiceClient {
enum CommandBatchProcessedResult {
virtual ~CommandBufferServiceClient() = default;
// Called every time a batch of commands was processed by the
// CommandBufferService. The return value indicates whether the
// CommandBufferService should continue execution of commands or pause it.
virtual CommandBatchProcessedResult OnCommandBatchProcessed() = 0;
// Called when the CommandBufferService gets into an error state.
virtual void OnParseError() = 0;
union CommandBufferEntry;
// An object that implements a shared memory command buffer and a synchronous
// API to manage the put and get pointers.
class GPU_EXPORT CommandBufferService : public CommandBufferServiceBase {
static const int kParseCommandsSlice = 20;
CommandBufferService(CommandBufferServiceClient* client,
TransferBufferManager* transfer_buffer_manager);
~CommandBufferService() override;
// CommandBufferServiceBase implementation:
CommandBuffer::State GetState() override;
void SetReleaseCount(uint64_t release_count) override;
scoped_refptr<Buffer> GetTransferBuffer(int32_t id) override;
void SetToken(int32_t token) override;
void SetParseError(error::Error error) override;
void SetContextLostReason(error::ContextLostReason) override;
// Setup the shared memory that shared state should be copied into.
void SetSharedStateBuffer(std::unique_ptr<BufferBacking> shared_state_buffer);
// Increments the generation and copies the current state into the shared
// state transfer buffer.
void UpdateState();
// Flushes up to the put_offset and execute commands with the handler.
void Flush(int32_t put_offset, AsyncAPIInterface* handler);
// Sets the get buffer and call the GetBufferChangeCallback.
void SetGetBuffer(int32_t transfer_buffer_id);
// Registers an existing Buffer object with a given ID that can be used to
// identify it in the command buffer.
bool RegisterTransferBuffer(int32_t id, scoped_refptr<Buffer> buffer);
// Unregisters and destroys the transfer buffer associated with the given id.
void DestroyTransferBuffer(int32_t id);
// Creates an in-process transfer buffer and register it with a newly created
// id.
scoped_refptr<Buffer> CreateTransferBuffer(size_t size, int32_t* id);
// Creates an in-process transfer buffer and register it with a given id.
scoped_refptr<Buffer> CreateTransferBufferWithId(size_t size, int32_t id);
// Sets whether commands should be processed by this scheduler. Setting to
// false unschedules. Setting to true reschedules.
void SetScheduled(bool scheduled);
bool scheduled() const { return scheduled_; }
int32_t put_offset() const { return put_offset_; }
void SetGetOffsetForTest(int32_t get_offset) {
state_.get_offset = get_offset;
CommandBufferServiceClient* client_;
TransferBufferManager* transfer_buffer_manager_;
CommandBuffer::State state_;
int32_t put_offset_ = 0;
int32_t num_entries_ = 0;
scoped_refptr<Buffer> ring_buffer_;
volatile CommandBufferEntry* buffer_ = nullptr;
std::unique_ptr<BufferBacking> shared_state_buffer_;
CommandBufferSharedState* shared_state_ = nullptr;
// Whether the scheduler is currently able to process more commands.
bool scheduled_ = true;
bool paused_ = false;
} // namespace gpu