blob: 3cc847235cd7d04c33b44a66fa7f5ac851ed19e3 [file] [log] [blame]
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#pragma once
#include <memory>
#include <string>
#include "flutter/fml/macros.h"
#include "impeller/core/capture.h"
#include "impeller/core/formats.h"
#include "impeller/core/host_buffer.h"
#include "impeller/renderer/capabilities.h"
#include "impeller/renderer/pool.h"
namespace impeller {
class ShaderLibrary;
class SamplerLibrary;
class CommandBuffer;
class PipelineLibrary;
class Allocator;
//------------------------------------------------------------------------------
/// @brief To do anything rendering related with Impeller, you need a
/// context.
///
/// Contexts are expensive to construct and typically you only need
/// one in the process. The context represents a connection to a
/// graphics or compute accelerator on the device.
///
/// If there are multiple context in a process, it would typically
/// be for separation of concerns (say, use with multiple engines in
/// Flutter), talking to multiple accelerators, or talking to the
/// same accelerator using different client APIs (Metal, Vulkan,
/// OpenGL ES, etc..).
///
/// Contexts are thread-safe. They may be created, used, and
/// collected (though not from a thread used by an internal pool) on
/// any thread. They may also be accessed simultaneously from
/// multiple threads.
///
/// Contexts are abstract and a concrete instance must be created
/// using one of the subclasses of `Context` in
/// `//impeller/renderer/backend`.
class Context {
public:
enum class BackendType {
kMetal,
kOpenGLES,
kVulkan,
};
//----------------------------------------------------------------------------
/// @brief Destroys an Impeller context.
///
virtual ~Context();
//----------------------------------------------------------------------------
/// @brief Get the graphics backend of an Impeller context.
///
/// This is useful for cases where a renderer needs to track and
/// lookup backend-specific resources, like shaders or uniform
/// layout information.
///
/// It's not recommended to use this as a substitute for
/// per-backend capability checking. Instead, check for specific
/// capabilities via `GetCapabilities()`.
///
/// @return The graphics backend of the `Context`.
///
virtual BackendType GetBackendType() const = 0;
// TODO(129920): Refactor and move to capabilities.
virtual std::string DescribeGpuModel() const = 0;
//----------------------------------------------------------------------------
/// @brief Determines if a context is valid. If the caller ever receives
/// an invalid context, they must discard it and construct a new
/// context. There is no recovery mechanism to repair a bad
/// context.
///
/// It is convention in Impeller to never return an invalid
/// context from a call that returns an pointer to a context. The
/// call implementation performs validity checks itself and return
/// a null context instead of a pointer to an invalid context.
///
/// How a context goes invalid is backend specific. It could
/// happen due to device loss, or any other unrecoverable error.
///
/// @return If the context is valid.
///
virtual bool IsValid() const = 0;
//----------------------------------------------------------------------------
/// @brief Get the capabilities of Impeller context. All optionally
/// supported feature of the platform, client-rendering API, and
/// device can be queried using the `Capabilities`.
///
/// @return The capabilities. Can never be `nullptr` for a valid context.
///
virtual const std::shared_ptr<const Capabilities>& GetCapabilities()
const = 0;
// TODO(129920): Refactor and move to capabilities.
virtual bool UpdateOffscreenLayerPixelFormat(PixelFormat format);
//----------------------------------------------------------------------------
/// @brief Returns the allocator used to create textures and buffers on
/// the device.
///
/// @return The resource allocator. Can never be `nullptr` for a valid
/// context.
///
virtual std::shared_ptr<Allocator> GetResourceAllocator() const = 0;
//----------------------------------------------------------------------------
/// @brief Returns the library of shaders used to specify the
/// programmable stages of a pipeline.
///
/// @return The shader library. Can never be `nullptr` for a valid
/// context.
///
virtual std::shared_ptr<ShaderLibrary> GetShaderLibrary() const = 0;
//----------------------------------------------------------------------------
/// @brief Returns the library of combined image samplers used in
/// shaders.
///
/// @return The sampler library. Can never be `nullptr` for a valid
/// context.
///
virtual std::shared_ptr<SamplerLibrary> GetSamplerLibrary() const = 0;
//----------------------------------------------------------------------------
/// @brief Returns the library of pipelines used by render or compute
/// commands.
///
/// @return The pipeline library. Can never be `nullptr` for a valid
/// context.
///
virtual std::shared_ptr<PipelineLibrary> GetPipelineLibrary() const = 0;
//----------------------------------------------------------------------------
/// @brief Create a new command buffer. Command buffers can be used to
/// encode graphics, blit, or compute commands to be submitted to
/// the device.
///
/// A command buffer can only be used on a single thread.
/// Multi-threaded render, blit, or compute passes must create a
/// new command buffer on each thread.
///
/// @return A new command buffer.
///
virtual std::shared_ptr<CommandBuffer> CreateCommandBuffer() const = 0;
//----------------------------------------------------------------------------
/// @brief Force all pending asynchronous work to finish. This is
/// achieved by deleting all owned concurrent message loops.
///
virtual void Shutdown() = 0;
//----------------------------------------------------------------------------
/// @brief Force the Vulkan presentation (submitKHR) to be performed on
/// the raster task runner.
///
/// This is required for correct rendering on Android when using
/// the hybrid composition mode. This has no effect on other
/// backends.
virtual void SetSyncPresentation(bool value) {}
//----------------------------------------------------------------------------
/// @brief Accessor for a pool of HostBuffers.
Pool<HostBuffer>& GetHostBufferPool() const { return host_buffer_pool_; }
CaptureContext capture;
protected:
Context();
private:
mutable Pool<HostBuffer> host_buffer_pool_ = Pool<HostBuffer>(1'000'000);
FML_DISALLOW_COPY_AND_ASSIGN(Context);
};
} // namespace impeller