Skip to content

Commit

Permalink
Merge pull request #3114 from MirServer/better-better-display-names
Browse files Browse the repository at this point in the history
Platform: Better names and responsibilities for platform types
  • Loading branch information
AlanGriffiths authored Nov 2, 2023
2 parents 5a9c122 + af1d40c commit 7f05753
Show file tree
Hide file tree
Showing 72 changed files with 932 additions and 930 deletions.
55 changes: 52 additions & 3 deletions include/platform/mir/graphics/display_buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#ifndef MIR_GRAPHICS_DISPLAY_BUFFER_H_
#define MIR_GRAPHICS_DISPLAY_BUFFER_H_

#include "mir/graphics/platform.h"
#include <mir/geometry/rectangle.h>
#include <mir/graphics/renderable.h>
#include <mir_toolkit/common.h>
Expand Down Expand Up @@ -61,9 +62,9 @@ class DisplayBuffer
/** The size in pixels of the underlying display */
virtual auto pixel_size() const -> geometry::Size = 0;

/** This will render renderlist to the screen and post the result to the
/** This will render renderlist to the screen and post the result to the
* screen if there is a hardware optimization that can be done.
* \param [in] renderlist
* \param [in] renderlist
* The renderables that should appear on the screen if the hardware
* is capable of optmizing that list somehow. If what you want
* displayed on the screen cannot be represented by a RenderableList,
Expand Down Expand Up @@ -98,8 +99,56 @@ class DisplayBuffer
*/
virtual glm::mat2 transformation() const = 0;

virtual auto display_provider() const -> std::shared_ptr<DisplayInterfaceProvider> = 0;
/**
* Attempt to acquire a platform-specific provider from this DisplayBuffer
*
* Any given platform is not guaranteed to implement any specific interface,
* and the set of supported interfaces may depend on the runtime environment.
*
* Since this may result in a runtime probe the call may be costly, and the
* result should be saved rather than re-acquiring an interface each time.
*
* \tparam Allocator
* \return On success: a non-null pointer to an Allocator implementation.
* The lifetime of this Allocator implementation is bound
* to that of the parent DisplayBuffer.
* On failure: nullptr
*/
template<typename Allocator>
auto acquire_allocator() -> Allocator*
{
static_assert(
std::is_convertible_v<Allocator*, DisplayAllocator*>,
"Can only acquire a DisplayAllocator; Provider must implement DisplayAllocator");

if (auto const base_interface = maybe_create_allocator(typename Allocator::Tag{}))
{
if (auto const requested_interface = dynamic_cast<Allocator*>(base_interface))
{
return requested_interface;
}
BOOST_THROW_EXCEPTION((std::logic_error{
"Implementation error! Platform returned object that does not support requested interface"}));
}
return nullptr;
}

protected:
/**
* Acquire a specific hardware interface
*
* This should perform any runtime checks necessary to verify the requested interface is
* expected to work and return a pointer to an implementation of that interface.
*
* \param type_tag [in] An instance of the Tag type for the requested interface.
* Implementations are expected to dynamic_cast<> this to
* discover the specific interface being requested.
* \return A pointer to an implementation of the DisplayAllocator-derived
* interface that corresponds to the most-derived type of tag_type.
*/
virtual auto maybe_create_allocator(DisplayAllocator::Tag const& type_tag)
-> DisplayAllocator* = 0;

DisplayBuffer() = default;
DisplayBuffer(DisplayBuffer const& c) = delete;
DisplayBuffer& operator=(DisplayBuffer const& c) = delete;
Expand Down
139 changes: 82 additions & 57 deletions include/platform/mir/graphics/platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,6 @@ class DisplayConfigurationPolicy;
class GraphicBufferAllocator;
class GLConfig;

class DisplayInterfaceProvider;

namespace probe
{
/**
Expand Down Expand Up @@ -130,9 +128,9 @@ class RenderingProvider
};

/**
* Check how well this Renderer can support a particular display target
*/
virtual auto suitability_for_display(std::shared_ptr<DisplayInterfaceProvider> const& target)
* Check how well this Renderer can support a particular display target
*/
virtual auto suitability_for_display(DisplayBuffer& target)
-> probe::Result = 0;

/**
Expand All @@ -141,7 +139,7 @@ class RenderingProvider
virtual auto suitability_for_allocator(std::shared_ptr<GraphicBufferAllocator> const& target)
-> probe::Result = 0;

virtual auto make_framebuffer_provider(std::shared_ptr<DisplayInterfaceProvider> target)
virtual auto make_framebuffer_provider(DisplayBuffer& target)
-> std::unique_ptr<FramebufferProvider> = 0;
};

Expand All @@ -161,7 +159,7 @@ class GLRenderingProvider : public RenderingProvider
virtual auto as_texture(std::shared_ptr<Buffer> buffer) -> std::shared_ptr<gl::Texture> = 0;

virtual auto surface_for_output(
std::shared_ptr<DisplayInterfaceProvider> framebuffer_provider,
DisplayBuffer& target,
geometry::Size size,
GLConfig const& config) -> std::unique_ptr<gl::OutputSurface> = 0;
};
Expand Down Expand Up @@ -258,6 +256,19 @@ class DisplayProvider
};


class DisplayAllocator
{
public:
class Tag
{
public:
Tag() = default;
virtual ~Tag() = default;
};

virtual ~DisplayAllocator() = default;
};

class Framebuffer
{
public:
Expand All @@ -270,13 +281,20 @@ class Framebuffer
virtual auto size() const -> geometry::Size = 0;
};


class CPUAddressableDisplayProvider : public DisplayProvider
{
public:
class Tag : public DisplayProvider::Tag
{
};
};

class CPUAddressableDisplayAllocator : public DisplayAllocator
{
public:
class Tag : public DisplayAllocator::Tag
{
};

class MappableFB :
public Framebuffer,
Expand Down Expand Up @@ -308,15 +326,28 @@ class GBMDisplayProvider : public DisplayProvider
* the provided device is a Rendernode associated with the display hardware
*/
virtual auto is_same_device(mir::udev::Device const& render_device) const -> bool = 0;


/**
* Check if this DisplayBuffer is driven by this DisplayProvider
*/
virtual auto on_this_device(DisplayBuffer& target) const -> bool = 0;

/**
* Get the GBM device for this display
*/
virtual auto gbm_device() const -> std::shared_ptr<struct gbm_device> = 0;
};

class GBMDisplayAllocator : public DisplayAllocator
{
public:
class Tag : public DisplayAllocator::Tag
{
};

/**
* Formats supported for output
*/
/**
* Formats supported for output
*/
virtual auto supported_formats() const -> std::vector<DRMFormat> = 0;

/**
Expand All @@ -335,7 +366,7 @@ class GBMDisplayProvider : public DisplayProvider
/**
* Commit the current EGL front buffer as a KMS-displayable Framebuffer
*
* Like the underlying gbm_sufrace_lock_front_buffer GBM API, it is a this
* Like the underlying gbm_sufrace_lock_front_buffer GBM API, this
* must be called after at least one call to eglSwapBuffers, and at most
* once per eglSwapBuffers call.
*
Expand All @@ -351,10 +382,10 @@ class GBMDisplayProvider : public DisplayProvider

class DmaBufBuffer;

class DmaBufDisplayProvider : public DisplayProvider
class DmaBufDisplayAllocator : public DisplayAllocator
{
public:
class Tag : public DisplayProvider::Tag
class Tag : public DisplayAllocator::Tag
{
};

Expand All @@ -374,6 +405,14 @@ class EGLStreamDisplayProvider : public DisplayProvider
};

virtual auto get_egl_display() const -> EGLDisplay = 0;
};

class EGLStreamDisplayAllocator : public DisplayAllocator
{
public:
class Tag : public DisplayAllocator::Tag
{
};

virtual auto claim_stream() -> EGLStreamKHR = 0;
};
Expand All @@ -386,6 +425,14 @@ class GenericEGLDisplayProvider : public DisplayProvider
};

virtual auto get_egl_display() -> EGLDisplay = 0;
};

class GenericEGLDisplayAllocator : public DisplayAllocator
{
public:
class Tag : public DisplayAllocator::Tag
{
};

class EGLFramebuffer : public graphics::Framebuffer
{
Expand All @@ -398,14 +445,21 @@ class GenericEGLDisplayProvider : public DisplayProvider
virtual auto alloc_framebuffer(GLConfig const& config, EGLContext share_context) -> std::unique_ptr<EGLFramebuffer> = 0;
};

class DisplayInterfaceProvider : public std::enable_shared_from_this<DisplayInterfaceProvider>
class DisplayPlatform
{
public:
DisplayInterfaceProvider() = default;
virtual ~DisplayInterfaceProvider() = default;
DisplayPlatform() = default;
DisplayPlatform(DisplayPlatform const& p) = delete;
DisplayPlatform& operator=(DisplayPlatform const& p) = delete;

virtual ~DisplayPlatform() = default;

DisplayInterfaceProvider(DisplayInterfaceProvider const&) = delete;
auto operator=(DisplayInterfaceProvider const&) -> DisplayInterfaceProvider& = delete;
/**
* Creates the display subsystem.
*/
virtual UniqueModulePtr<Display> create_display(
std::shared_ptr<DisplayConfigurationPolicy> const& initial_conf_policy,
std::shared_ptr<GLConfig> const& gl_config) = 0;

/**
* Attempt to acquire a platform-specific interface from this DisplayPlatform
Expand All @@ -421,13 +475,13 @@ class DisplayInterfaceProvider : public std::enable_shared_from_this<DisplayInte
* On failure: std::shared_ptr<Interface>{nullptr}
*/
template<typename Interface>
auto acquire_interface() -> std::shared_ptr<Interface>
auto acquire_provider() -> std::shared_ptr<Interface>
{
static_assert(
std::is_convertible_v<Interface*, DisplayProvider*>,
"Can only acquire a Display interface; Interface must implement DisplayProvider");

if (auto const base_interface = maybe_create_interface(typename Interface::Tag{}))
if (auto const base_interface = maybe_create_provider(typename Interface::Tag{}))
{
if (auto const requested_interface = std::dynamic_pointer_cast<Interface>(base_interface))
{
Expand All @@ -437,7 +491,7 @@ class DisplayInterfaceProvider : public std::enable_shared_from_this<DisplayInte
"Implementation error! Platform returned object that does not support requested interface"}));
}
return nullptr;
}
}

protected:
/**
Expand All @@ -446,45 +500,16 @@ class DisplayInterfaceProvider : public std::enable_shared_from_this<DisplayInte
* This should perform any runtime checks necessary to verify the requested interface is
* expected to work and return a pointer to an implementation of that interface.
*
* This function is guaranteed to be called with `this` managed by a `shared_ptr`; if
* the returned value needs to share ownership with `this`, calls to `std::shared_from_this`
* can be expected to work.
*
* \param type_tag [in] An instance of the Tag type for the requested interface.
* Implementations are expected to dynamic_cast<> this to
* discover the specific interface being requested.
* \return A pointer to an implementation of the DisplayProvider-derived
* interface that corresponds to the most-derived type of tag_type.
*/
virtual auto maybe_create_interface(DisplayProvider::Tag const& type_tag)
virtual auto maybe_create_provider(DisplayProvider::Tag const& type_tag)
-> std::shared_ptr<DisplayProvider> = 0;
};

class DisplayPlatform : public std::enable_shared_from_this<DisplayPlatform>
{
public:
DisplayPlatform() = default;
DisplayPlatform(DisplayPlatform const& p) = delete;
DisplayPlatform& operator=(DisplayPlatform const& p) = delete;

virtual ~DisplayPlatform() = default;

/**
* Creates the display subsystem.
*/
virtual UniqueModulePtr<Display> create_display(
std::shared_ptr<DisplayConfigurationPolicy> const& initial_conf_policy,
std::shared_ptr<GLConfig> const& gl_config) = 0;

static auto interface_for(std::shared_ptr<DisplayPlatform> platform)
-> std::shared_ptr<DisplayInterfaceProvider>
{
return platform->interface_for();
}
protected:
virtual auto interface_for() -> std::shared_ptr<DisplayInterfaceProvider> = 0;
};

struct SupportedDevice
{
/**
Expand Down Expand Up @@ -520,7 +545,7 @@ typedef mir::UniqueModulePtr<mir::graphics::DisplayPlatform>(*CreateDisplayPlatf

typedef mir::UniqueModulePtr<mir::graphics::RenderingPlatform>(*CreateRenderPlatform)(
mir::graphics::SupportedDevice const& device,
std::vector<std::shared_ptr<mir::graphics::DisplayInterfaceProvider>> const& displays,
std::vector<std::shared_ptr<mir::graphics::DisplayPlatform>> const& platforms,
mir::options::Option const& options,
mir::EmergencyCleanupRegistry& emergency_cleanup_registry);

Expand All @@ -533,7 +558,7 @@ typedef std::vector<mir::graphics::SupportedDevice>(*PlatformProbe)(
mir::options::ProgramOption const& options);

typedef std::vector<mir::graphics::SupportedDevice>(*RenderProbe)(
std::span<std::shared_ptr<mir::graphics::DisplayInterfaceProvider>> const&,
std::span<std::shared_ptr<mir::graphics::DisplayPlatform>> const&,
mir::ConsoleServices&,
std::shared_ptr<mir::udev::Context> const&,
mir::options::ProgramOption const&);
Expand Down Expand Up @@ -574,7 +599,7 @@ mir::UniqueModulePtr<mir::graphics::DisplayPlatform> create_display_platform(

mir::UniqueModulePtr<mir::graphics::RenderingPlatform> create_rendering_platform(
mir::graphics::SupportedDevice const& device,
std::vector<std::shared_ptr<mir::graphics::DisplayInterfaceProvider>> const& displays,
std::vector<std::shared_ptr<mir::graphics::DisplayPlatform>> const& targets,
mir::options::Option const& options,
mir::EmergencyCleanupRegistry& emergency_cleanup_registry);

Expand All @@ -597,7 +622,7 @@ auto probe_display_platform(
mir::options::ProgramOption const& options) -> std::vector<mir::graphics::SupportedDevice>;

auto probe_rendering_platform(
std::span<std::shared_ptr<mir::graphics::DisplayInterfaceProvider>> const& display_providers,
std::span<std::shared_ptr<mir::graphics::DisplayPlatform>> const& targets,
mir::ConsoleServices& console,
std::shared_ptr<mir::udev::Context> const& udev,
mir::options::ProgramOption const& options) -> std::vector<mir::graphics::SupportedDevice>;
Expand Down
2 changes: 1 addition & 1 deletion src/platforms/common/server/cpu_addressable_fb.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

namespace mir::graphics
{
class CPUAddressableFB : public FBHandle, public CPUAddressableDisplayProvider::MappableFB
class CPUAddressableFB : public FBHandle, public CPUAddressableDisplayAllocator::MappableFB
{
public:
CPUAddressableFB(
Expand Down
Loading

0 comments on commit 7f05753

Please sign in to comment.