#ifndef UI_OZONE_PLATFORM_DRM_GPU_DRM_THREAD_H_
#define UI_OZONE_PLATFORM_DRM_GPU_DRM_THREAD_H_
#include <stdint.h>
#include <memory>
#include <optional>
#include <vector>
#include "base/files/file.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/threading/thread.h"
#include "mojo/public/cpp/bindings/associated_receiver_set.h"
#include "mojo/public/cpp/bindings/pending_associated_receiver.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/receiver_set.h"
#include "ui/gfx/native_pixmap_handle.h"
#include "ui/gfx/native_ui_types.h"
#include "ui/ozone/platform/drm/common/display_types.h"
#include "ui/ozone/platform/drm/gpu/drm_device_generator.h"
#include "ui/ozone/platform/drm/mojom/device_cursor.mojom.h"
#include "ui/ozone/platform/drm/mojom/drm_device.mojom.h"
#include "ui/ozone/public/drm_modifiers_filter.h"
#include "ui/ozone/public/hardware_capabilities.h"
#include "ui/ozone/public/native_pixmap_usage.h"
#include "ui/ozone/public/overlay_surface_candidate.h"
#include "ui/ozone/public/swap_completion_callback.h"
namespace base {
class FilePath;
}
namespace display {
struct ColorCalibration;
struct ColorTemperatureAdjustment;
struct DisplayConfigurationParams;
struct GammaAdjustment;
}
namespace gfx {
class Point;
class Rect;
}
namespace ui {
class DrmDeviceManager;
class DrmFramebuffer;
class DrmGpuDisplayManager;
class GbmBuffer;
class ScreenManager;
struct DrmOverlayPlane;
class DrmThread : public base::Thread,
public ozone::mojom::DeviceCursor,
public ozone::mojom::DrmDevice {
public:
using OverlayCapabilitiesCallback =
base::OnceCallback<void(gfx::AcceleratedWidget,
const std::vector<OverlaySurfaceCandidate>&,
const std::vector<OverlayStatus>&)>;
DrmThread();
DrmThread(const DrmThread&) = delete;
DrmThread& operator=(const DrmThread&) = delete;
~DrmThread() override;
void Start(base::OnceClosure receiver_completer,
std::unique_ptr<DrmDeviceGenerator> device_generator);
void RunTaskAfterDeviceReady(base::OnceClosure task,
base::WaitableEvent* done);
void CreateBuffer(gfx::AcceleratedWidget widget,
const gfx::Size& size,
const gfx::Size& framebuffer_size,
viz::SharedImageFormat format,
NativePixmapUsageSet usage,
uint32_t flags,
std::unique_ptr<GbmBuffer>* buffer,
scoped_refptr<DrmFramebuffer>* framebuffer);
void CreateBufferFromHandle(gfx::AcceleratedWidget widget,
const gfx::Size& size,
viz::SharedImageFormat format,
gfx::NativePixmapHandle handle,
std::unique_ptr<GbmBuffer>* buffer,
scoped_refptr<DrmFramebuffer>* framebuffer);
void SetDisplaysConfiguredCallback(base::RepeatingClosure callback);
void AddDrmDeviceReceiver(
mojo::PendingReceiver<ozone::mojom::DrmDevice> receiver);
void CheckOverlayCapabilities(
gfx::AcceleratedWidget widget,
const std::vector<OverlaySurfaceCandidate>& candidates,
OverlayCapabilitiesCallback callback);
void CheckOverlayCapabilitiesSync(
gfx::AcceleratedWidget widget,
const std::vector<OverlaySurfaceCandidate>& candidates,
std::vector<OverlayStatus>* result);
void GetHardwareCapabilities(gfx::AcceleratedWidget widget,
HardwareCapabilitiesCallback receive_callback);
void SchedulePageFlip(gfx::AcceleratedWidget widget,
std::vector<DrmOverlayPlane> planes,
SwapCompletionOnceCallback submission_callback,
PresentationOnceCallback presentation_callback);
void IsDeviceAtomic(gfx::AcceleratedWidget widget, bool* is_atomic);
void SetDrmModifiersFilter(std::unique_ptr<DrmModifiersFilter> filter);
void CreateWindow(gfx::AcceleratedWidget widget,
const gfx::Rect& initial_bounds) override;
void DestroyWindow(gfx::AcceleratedWidget widget) override;
void SetWindowBounds(gfx::AcceleratedWidget widget,
const gfx::Rect& bounds) override;
void TakeDisplayControl(base::OnceCallback<void(bool)> callback) override;
void RelinquishDisplayControl(
base::OnceCallback<void(bool)> callback) override;
void ShouldDisplayEventTriggerConfiguration(
const EventPropertyMap& event_props,
base::OnceCallback<void(bool)> callback) override;
void RefreshNativeDisplays(
base::OnceCallback<void(MovableDisplaySnapshots)> callback) override;
void AddGraphicsDevice(const base::FilePath& path,
mojo::PlatformHandle fd_mojo_handle) override;
void RemoveGraphicsDevice(const base::FilePath& path) override;
void ConfigureNativeDisplays(
const std::vector<display::DisplayConfigurationParams>& config_requests,
display::ModesetFlags modeset_flags,
ConfigureNativeDisplaysCallback callback) override;
void SetHdcpKeyProp(int64_t display_id,
const std::string& key,
SetHdcpKeyPropCallback callback) override;
void GetHDCPState(int64_t display_id,
base::OnceCallback<void(int64_t,
bool,
display::HDCPState,
display::ContentProtectionMethod)>
callback) override;
void SetHDCPState(int64_t display_id,
display::HDCPState state,
display::ContentProtectionMethod protection_method,
base::OnceCallback<void(int64_t, bool)> callback) override;
void SetColorTemperatureAdjustment(
int64_t display_id,
const display::ColorTemperatureAdjustment& cta) override;
void SetColorCalibration(
int64_t display_id,
const display::ColorCalibration& calibration) override;
void SetGammaAdjustment(int64_t display_id,
const display::GammaAdjustment& adjustment) override;
void SetPrivacyScreen(int64_t display_id,
bool enabled,
base::OnceCallback<void(bool)> callback) override;
void GetSeamlessRefreshRates(
int64_t display_id,
GetSeamlessRefreshRatesCallback callback) override;
void GetDeviceCursor(
mojo::PendingAssociatedReceiver<ozone::mojom::DeviceCursor> receiver)
override;
void SetCursor(gfx::AcceleratedWidget widget,
const std::vector<SkBitmap>& bitmaps,
const std::optional<gfx::Point>& location,
base::TimeDelta frame_delay) override;
void MoveCursor(gfx::AcceleratedWidget widget,
const gfx::Point& location) override;
void Init() override;
void CleanUp() override;
private:
struct TaskInfo {
base::OnceClosure task;
raw_ptr<base::WaitableEvent> done;
TaskInfo(base::OnceClosure task, base::WaitableEvent* done);
TaskInfo(TaskInfo&& other);
~TaskInfo();
};
void OnPlanesReadyForPageFlip(gfx::AcceleratedWidget widget,
SwapCompletionOnceCallback submission_callback,
PresentationOnceCallback presentation_callback,
std::vector<DrmOverlayPlane> planes);
void ProcessPendingTasks();
std::unique_ptr<DrmDeviceManager> device_manager_;
std::unique_ptr<ScreenManager> screen_manager_;
std::unique_ptr<DrmGpuDisplayManager> display_manager_;
base::OnceClosure complete_early_receiver_requests_;
mojo::AssociatedReceiverSet<ozone::mojom::DeviceCursor> cursor_receivers_;
mojo::ReceiverSet<ozone::mojom::DrmDevice> drm_receivers_;
gfx::AcceleratedWidget last_created_window_ = gfx::kNullAcceleratedWidget;
std::vector<TaskInfo> pending_tasks_;
std::unique_ptr<DrmDeviceGenerator> device_generator_;
base::WeakPtrFactory<DrmThread> weak_ptr_factory_{this};
};
}
#endif