Index: ui/ozone/platform/drm/gpu/drm_thread.cc |
diff --git a/ui/ozone/platform/drm/gpu/drm_thread.cc b/ui/ozone/platform/drm/gpu/drm_thread.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..451293d45d0b652beab4c7f7d1b6e9e4b4cfa4b4 |
--- /dev/null |
+++ b/ui/ozone/platform/drm/gpu/drm_thread.cc |
@@ -0,0 +1,227 @@ |
+// Copyright 2015 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 "ui/ozone/platform/drm/gpu/drm_thread.h" |
+ |
+#include "base/command_line.h" |
+#include "base/thread_task_runner_handle.h" |
+#include "ui/ozone/platform/drm/gpu/drm_buffer.h" |
+#include "ui/ozone/platform/drm/gpu/drm_device_generator.h" |
+#include "ui/ozone/platform/drm/gpu/drm_device_manager.h" |
+#include "ui/ozone/platform/drm/gpu/drm_gpu_display_manager.h" |
+#include "ui/ozone/platform/drm/gpu/drm_window.h" |
+#include "ui/ozone/platform/drm/gpu/drm_window_proxy.h" |
+#include "ui/ozone/platform/drm/gpu/gbm_buffer.h" |
+#include "ui/ozone/platform/drm/gpu/gbm_device.h" |
+#include "ui/ozone/platform/drm/gpu/gbm_surface_factory.h" |
+#include "ui/ozone/platform/drm/gpu/proxy_helpers.h" |
+#include "ui/ozone/platform/drm/gpu/screen_manager.h" |
+#include "ui/ozone/public/ozone_switches.h" |
+ |
+namespace ui { |
+ |
+namespace { |
+ |
+class GbmBufferGenerator : public ScanoutBufferGenerator { |
+ public: |
+ GbmBufferGenerator() {} |
+ ~GbmBufferGenerator() override {} |
+ |
+ // ScanoutBufferGenerator: |
+ scoped_refptr<ScanoutBuffer> Create(const scoped_refptr<DrmDevice>& drm, |
+ gfx::BufferFormat format, |
+ const gfx::Size& size) override { |
+ scoped_refptr<GbmDevice> gbm(static_cast<GbmDevice*>(drm.get())); |
+ return GbmBuffer::CreateBuffer(gbm, format, size, |
+ gfx::BufferUsage::SCANOUT); |
+ } |
+ |
+ protected: |
+ DISALLOW_COPY_AND_ASSIGN(GbmBufferGenerator); |
+}; |
+ |
+class GbmDeviceGenerator : public DrmDeviceGenerator { |
+ public: |
+ GbmDeviceGenerator(bool use_atomic) : use_atomic_(use_atomic) {} |
+ ~GbmDeviceGenerator() override {} |
+ |
+ // DrmDeviceGenerator: |
+ scoped_refptr<DrmDevice> CreateDevice(const base::FilePath& path, |
+ base::File file) override { |
+ scoped_refptr<DrmDevice> drm = new GbmDevice(path, file.Pass()); |
+ if (drm->Initialize(use_atomic_)) |
+ return drm; |
+ |
+ return nullptr; |
+ } |
+ |
+ private: |
+ bool use_atomic_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(GbmDeviceGenerator); |
+}; |
+ |
+} // namespace |
+ |
+DrmThread::DrmThread() : base::Thread("DrmThread") {} |
+ |
+DrmThread::~DrmThread() { |
+ Stop(); |
+} |
+ |
+void DrmThread::Start() { |
+ if (!StartWithOptions(base::Thread::Options(base::MessageLoop::TYPE_IO, 0))) |
+ LOG(FATAL) << "Failed to create DRM thread"; |
+} |
+ |
+void DrmThread::Init() { |
+ bool use_atomic = false; |
+#if defined(USE_DRM_ATOMIC) |
+ use_atomic = true; |
+#endif |
+ |
+ device_manager_.reset(new DrmDeviceManager( |
+ make_scoped_ptr(new GbmDeviceGenerator(use_atomic)))); |
+ buffer_generator_.reset(new GbmBufferGenerator()); |
+ screen_manager_.reset(new ScreenManager(buffer_generator_.get())); |
+ |
+ display_manager_.reset( |
+ new DrmGpuDisplayManager(screen_manager_.get(), device_manager_.get())); |
+} |
+ |
+scoped_ptr<DrmWindowProxy> DrmThread::CreateWindowProxy( |
spang
2015/09/29 22:55:37
I think it is inconsistent to put it here. In ever
dnicoara
2015/09/30 15:17:57
Yeah, that was bugging me a bit too. The DrmWindow
|
+ gfx::AcceleratedWidget widget) { |
+ scoped_ptr<DrmWindowProxy> window; |
+ // The creation is synchronous on the DRM thread since it needs to make sure |
+ // that the window is created on the DRM thread before continuing. This is |
+ // required since the DrmDeviceManager is accessed on the GPU IO thread |
+ // without a posted task which could result in invalid lookups for the widget |
+ // if the window creation is still pending. |
+ PostSyncTask(task_runner(), |
+ base::Bind(&DrmThread::CreateWindowProxyOnThread, |
+ base::Unretained(this), widget, &window)); |
+ return window; |
+} |
+ |
+void DrmThread::SchedulePageFlip(gfx::AcceleratedWidget widget, |
+ const std::vector<OverlayPlane>& planes, |
+ const SwapCompletionCallback& callback) { |
+ DrmWindow* window = screen_manager_->GetWindow(widget); |
+ if (window) |
+ window->SchedulePageFlip(planes, callback); |
+} |
+ |
+void DrmThread::GetVSyncParameters( |
+ gfx::AcceleratedWidget widget, |
+ const gfx::VSyncProvider::UpdateVSyncCallback& callback) { |
+ DrmWindow* window = screen_manager_->GetWindow(widget); |
+ if (window) |
+ window->GetVSyncParameters(callback); |
+} |
+ |
+void DrmThread::OnCreateWindow(gfx::AcceleratedWidget widget) { |
spang
2015/09/29 22:55:37
We should use the imperative
CreateWindow()
OnCr
dnicoara
2015/09/30 15:17:57
Done. Sounds reasonable.
|
+ scoped_ptr<DrmWindow> window( |
+ new DrmWindow(widget, device_manager_.get(), screen_manager_.get())); |
+ window->Initialize(); |
+ screen_manager_->AddWindow(widget, window.Pass()); |
+} |
+ |
+void DrmThread::OnDestroyWindow(gfx::AcceleratedWidget widget) { |
+ scoped_ptr<DrmWindow> window = screen_manager_->RemoveWindow(widget); |
+ window->Shutdown(); |
+} |
+ |
+void DrmThread::OnWindowBoundsChanged(gfx::AcceleratedWidget widget, |
+ const gfx::Rect& bounds) { |
+ screen_manager_->GetWindow(widget)->OnBoundsChanged(bounds); |
+} |
+ |
+void DrmThread::OnCursorSet(gfx::AcceleratedWidget widget, |
+ const std::vector<SkBitmap>& bitmaps, |
+ const gfx::Point& location, |
+ int frame_delay_ms) { |
+ screen_manager_->GetWindow(widget) |
+ ->SetCursor(bitmaps, location, frame_delay_ms); |
+} |
+ |
+void DrmThread::OnCursorMove(gfx::AcceleratedWidget widget, |
+ const gfx::Point& location) { |
+ screen_manager_->GetWindow(widget)->MoveCursor(location); |
+} |
+ |
+void DrmThread::OnCheckOverlayCapabilities( |
+ gfx::AcceleratedWidget widget, |
+ const std::vector<OverlayCheck_Params>& overlays, |
+ const base::Callback<void(gfx::AcceleratedWidget, bool)>& callback) { |
+ callback.Run(widget, screen_manager_->GetWindow(widget) |
+ ->TestPageFlip(overlays, buffer_generator_.get())); |
+} |
+ |
+void DrmThread::OnRefreshNativeDisplays( |
+ const base::Callback<void(const std::vector<DisplaySnapshot_Params>&)>& |
+ callback) { |
+ callback.Run(display_manager_->GetDisplays()); |
+} |
+ |
+void DrmThread::OnConfigureNativeDisplay( |
+ int64_t id, |
+ const DisplayMode_Params& mode, |
+ const gfx::Point& origin, |
+ const base::Callback<void(int64_t, bool)>& callback) { |
+ callback.Run(id, display_manager_->ConfigureDisplay(id, mode, origin)); |
+} |
+ |
+void DrmThread::OnDisableNativeDisplay( |
+ int64_t id, |
+ const base::Callback<void(int64_t, bool)>& callback) { |
+ callback.Run(id, display_manager_->DisableDisplay(id)); |
+} |
+ |
+void DrmThread::OnTakeDisplayControl( |
+ const base::Callback<void(bool)>& callback) { |
+ callback.Run(display_manager_->TakeDisplayControl()); |
+} |
+ |
+void DrmThread::OnRelinquishDisplayControl( |
+ const base::Callback<void(bool)>& callback) { |
+ display_manager_->RelinquishDisplayControl(); |
+ callback.Run(true); |
+} |
+ |
+void DrmThread::OnAddGraphicsDevice(const base::FilePath& path, |
+ const base::FileDescriptor& fd) { |
+ device_manager_->AddDrmDevice(path, fd); |
+} |
+ |
+void DrmThread::OnRemoveGraphicsDevice(const base::FilePath& path) { |
+ device_manager_->RemoveDrmDevice(path); |
+} |
+ |
+void DrmThread::OnGetHDCPState( |
+ int64_t display_id, |
+ const base::Callback<void(int64_t, bool, HDCPState)>& callback) { |
+ HDCPState state = HDCP_STATE_UNDESIRED; |
+ bool success = display_manager_->GetHDCPState(display_id, &state); |
+ callback.Run(display_id, success, state); |
+} |
+ |
+void DrmThread::OnSetHDCPState( |
+ int64_t display_id, |
+ HDCPState state, |
+ const base::Callback<void(int64_t, bool)>& callback) { |
+ callback.Run(display_id, display_manager_->SetHDCPState(display_id, state)); |
+} |
+ |
+void DrmThread::OnSetGammaRamp(int64_t id, |
+ const std::vector<GammaRampRGBEntry>& lut) { |
+ display_manager_->SetGammaRamp(id, lut); |
+} |
+ |
+void DrmThread::CreateWindowProxyOnThread(gfx::AcceleratedWidget widget, |
+ scoped_ptr<DrmWindowProxy>* window) { |
+ if (screen_manager_->GetWindow(widget)) |
+ window->reset(new DrmWindowProxy(widget, this)); |
+} |
+ |
+} // namespace ui |