| Index: ui/ozone/platform/dri/dri_wrapper.cc
|
| diff --git a/ui/ozone/platform/dri/dri_wrapper.cc b/ui/ozone/platform/dri/dri_wrapper.cc
|
| deleted file mode 100644
|
| index 87b250ec9011a96eb0df91018fb6acd4019b3386..0000000000000000000000000000000000000000
|
| --- a/ui/ozone/platform/dri/dri_wrapper.cc
|
| +++ /dev/null
|
| @@ -1,461 +0,0 @@
|
| -// Copyright 2014 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/dri/dri_wrapper.h"
|
| -
|
| -#include <fcntl.h>
|
| -#include <sys/mman.h>
|
| -#include <unistd.h>
|
| -#include <xf86drm.h>
|
| -#include <xf86drmMode.h>
|
| -
|
| -#include "base/logging.h"
|
| -#include "base/message_loop/message_loop.h"
|
| -#include "base/stl_util.h"
|
| -#include "base/synchronization/waitable_event.h"
|
| -#include "base/task_runner.h"
|
| -#include "base/thread_task_runner_handle.h"
|
| -#include "base/trace_event/trace_event.h"
|
| -#include "third_party/skia/include/core/SkImageInfo.h"
|
| -#include "ui/ozone/platform/dri/dri_util.h"
|
| -#include "ui/ozone/platform/dri/hardware_display_plane_manager_legacy.h"
|
| -
|
| -namespace ui {
|
| -
|
| -namespace {
|
| -
|
| -struct PageFlipPayload {
|
| - PageFlipPayload(const scoped_refptr<base::TaskRunner>& task_runner,
|
| - const DriWrapper::PageFlipCallback& callback)
|
| - : task_runner(task_runner), callback(callback) {}
|
| -
|
| - // Task runner for the thread scheduling the page flip event. This is used to
|
| - // run the callback on the same thread the callback was created on.
|
| - scoped_refptr<base::TaskRunner> task_runner;
|
| - DriWrapper::PageFlipCallback callback;
|
| -};
|
| -
|
| -bool DrmCreateDumbBuffer(int fd,
|
| - const SkImageInfo& info,
|
| - uint32_t* handle,
|
| - uint32_t* stride) {
|
| - struct drm_mode_create_dumb request;
|
| - memset(&request, 0, sizeof(request));
|
| - request.width = info.width();
|
| - request.height = info.height();
|
| - request.bpp = info.bytesPerPixel() << 3;
|
| - request.flags = 0;
|
| -
|
| - if (drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &request) < 0) {
|
| - VLOG(2) << "Cannot create dumb buffer (" << errno << ") "
|
| - << strerror(errno);
|
| - return false;
|
| - }
|
| -
|
| - // The driver may choose to align the last row as well. We don't care about
|
| - // the last alignment bits since they aren't used for display purposes, so
|
| - // just check that the expected size is <= to what the driver allocated.
|
| - DCHECK_LE(info.getSafeSize(request.pitch), request.size);
|
| -
|
| - *handle = request.handle;
|
| - *stride = request.pitch;
|
| - return true;
|
| -}
|
| -
|
| -void DrmDestroyDumbBuffer(int fd, uint32_t handle) {
|
| - struct drm_mode_destroy_dumb destroy_request;
|
| - memset(&destroy_request, 0, sizeof(destroy_request));
|
| - destroy_request.handle = handle;
|
| - drmIoctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_request);
|
| -}
|
| -
|
| -void HandlePageFlipEventOnIO(int fd,
|
| - unsigned int frame,
|
| - unsigned int seconds,
|
| - unsigned int useconds,
|
| - void* data) {
|
| - scoped_ptr<PageFlipPayload> payload(static_cast<PageFlipPayload*>(data));
|
| - payload->task_runner->PostTask(
|
| - FROM_HERE, base::Bind(payload->callback, frame, seconds, useconds));
|
| -}
|
| -
|
| -void HandlePageFlipEventOnUI(int fd,
|
| - unsigned int frame,
|
| - unsigned int seconds,
|
| - unsigned int useconds,
|
| - void* data) {
|
| - scoped_ptr<PageFlipPayload> payload(static_cast<PageFlipPayload*>(data));
|
| - payload->callback.Run(frame, seconds, useconds);
|
| -}
|
| -
|
| -bool CanQueryForResources(int fd) {
|
| - drm_mode_card_res resources;
|
| - memset(&resources, 0, sizeof(resources));
|
| - // If there is no error getting DRM resources then assume this is a
|
| - // modesetting device.
|
| - return !drmIoctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &resources);
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| -class DriWrapper::IOWatcher
|
| - : public base::RefCountedThreadSafe<DriWrapper::IOWatcher>,
|
| - public base::MessagePumpLibevent::Watcher {
|
| - public:
|
| - IOWatcher(int fd,
|
| - const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner)
|
| - : io_task_runner_(io_task_runner), paused_(true), fd_(fd) {}
|
| -
|
| - void SetPaused(bool paused) {
|
| - if (paused_ == paused)
|
| - return;
|
| -
|
| - paused_ = paused;
|
| - base::WaitableEvent done(false, false);
|
| - io_task_runner_->PostTask(
|
| - FROM_HERE, base::Bind(&IOWatcher::SetPausedOnIO, this, &done));
|
| - }
|
| -
|
| - void Shutdown() {
|
| - if (!paused_)
|
| - io_task_runner_->PostTask(FROM_HERE,
|
| - base::Bind(&IOWatcher::UnregisterOnIO, this));
|
| - }
|
| -
|
| - private:
|
| - friend class base::RefCountedThreadSafe<IOWatcher>;
|
| -
|
| - ~IOWatcher() override { SetPaused(true); }
|
| -
|
| - void RegisterOnIO() {
|
| - DCHECK(base::MessageLoopForIO::IsCurrent());
|
| - base::MessageLoopForIO::current()->WatchFileDescriptor(
|
| - fd_, true, base::MessageLoopForIO::WATCH_READ, &controller_, this);
|
| - }
|
| -
|
| - void UnregisterOnIO() {
|
| - DCHECK(base::MessageLoopForIO::IsCurrent());
|
| - controller_.StopWatchingFileDescriptor();
|
| - }
|
| -
|
| - void SetPausedOnIO(base::WaitableEvent* done) {
|
| - DCHECK(base::MessageLoopForIO::IsCurrent());
|
| - if (paused_)
|
| - UnregisterOnIO();
|
| - else
|
| - RegisterOnIO();
|
| - done->Signal();
|
| - }
|
| -
|
| - // base::MessagePumpLibevent::Watcher overrides:
|
| - void OnFileCanReadWithoutBlocking(int fd) override {
|
| - DCHECK(base::MessageLoopForIO::IsCurrent());
|
| - TRACE_EVENT1("dri", "OnDrmEvent", "socket", fd);
|
| -
|
| - drmEventContext event;
|
| - event.version = DRM_EVENT_CONTEXT_VERSION;
|
| - event.page_flip_handler = HandlePageFlipEventOnIO;
|
| - event.vblank_handler = nullptr;
|
| -
|
| - drmHandleEvent(fd, &event);
|
| - }
|
| -
|
| - void OnFileCanWriteWithoutBlocking(int fd) override { NOTREACHED(); }
|
| -
|
| - scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
|
| -
|
| - base::MessagePumpLibevent::FileDescriptorWatcher controller_;
|
| -
|
| - bool paused_;
|
| - int fd_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(IOWatcher);
|
| -};
|
| -
|
| -DriWrapper::DriWrapper(const base::FilePath& device_path)
|
| - : device_path_(device_path),
|
| - file_(device_path,
|
| - base::File::FLAG_OPEN | base::File::FLAG_READ |
|
| - base::File::FLAG_WRITE) {
|
| - LOG_IF(FATAL, !file_.IsValid())
|
| - << "Failed to open '" << device_path_.value()
|
| - << "': " << base::File::ErrorToString(file_.error_details());
|
| -}
|
| -
|
| -DriWrapper::DriWrapper(const base::FilePath& device_path, base::File file)
|
| - : device_path_(device_path), file_(file.Pass()) {
|
| -}
|
| -
|
| -DriWrapper::~DriWrapper() {
|
| - if (watcher_)
|
| - watcher_->Shutdown();
|
| -}
|
| -
|
| -bool DriWrapper::Initialize() {
|
| - // Ignore devices that cannot perform modesetting.
|
| - if (!CanQueryForResources(file_.GetPlatformFile())) {
|
| - VLOG(2) << "Cannot query for resources for '" << device_path_.value()
|
| - << "'";
|
| - return false;
|
| - }
|
| -
|
| - plane_manager_.reset(new HardwareDisplayPlaneManagerLegacy());
|
| - if (!plane_manager_->Initialize(this)) {
|
| - LOG(ERROR) << "Failed to initialize the plane manager for "
|
| - << device_path_.value();
|
| - plane_manager_.reset();
|
| - return false;
|
| - }
|
| -
|
| - return true;
|
| -}
|
| -
|
| -void DriWrapper::InitializeTaskRunner(
|
| - const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) {
|
| - DCHECK(!task_runner_);
|
| - task_runner_ = task_runner;
|
| - watcher_ = new IOWatcher(file_.GetPlatformFile(), task_runner_);
|
| -}
|
| -
|
| -ScopedDrmCrtcPtr DriWrapper::GetCrtc(uint32_t crtc_id) {
|
| - DCHECK(file_.IsValid());
|
| - return ScopedDrmCrtcPtr(drmModeGetCrtc(file_.GetPlatformFile(), crtc_id));
|
| -}
|
| -
|
| -bool DriWrapper::SetCrtc(uint32_t crtc_id,
|
| - uint32_t framebuffer,
|
| - std::vector<uint32_t> connectors,
|
| - drmModeModeInfo* mode) {
|
| - DCHECK(file_.IsValid());
|
| - DCHECK(!connectors.empty());
|
| - DCHECK(mode);
|
| -
|
| - TRACE_EVENT2("dri", "DriWrapper::SetCrtc", "crtc", crtc_id, "size",
|
| - gfx::Size(mode->hdisplay, mode->vdisplay).ToString());
|
| - return !drmModeSetCrtc(file_.GetPlatformFile(), crtc_id, framebuffer, 0, 0,
|
| - vector_as_array(&connectors), connectors.size(), mode);
|
| -}
|
| -
|
| -bool DriWrapper::SetCrtc(drmModeCrtc* crtc, std::vector<uint32_t> connectors) {
|
| - DCHECK(file_.IsValid());
|
| - // If there's no buffer then the CRTC was disabled.
|
| - if (!crtc->buffer_id)
|
| - return DisableCrtc(crtc->crtc_id);
|
| -
|
| - DCHECK(!connectors.empty());
|
| -
|
| - TRACE_EVENT1("dri", "DriWrapper::RestoreCrtc",
|
| - "crtc", crtc->crtc_id);
|
| - return !drmModeSetCrtc(file_.GetPlatformFile(), crtc->crtc_id,
|
| - crtc->buffer_id, crtc->x, crtc->y,
|
| - vector_as_array(&connectors), connectors.size(),
|
| - &crtc->mode);
|
| -}
|
| -
|
| -bool DriWrapper::DisableCrtc(uint32_t crtc_id) {
|
| - DCHECK(file_.IsValid());
|
| - TRACE_EVENT1("dri", "DriWrapper::DisableCrtc",
|
| - "crtc", crtc_id);
|
| - return !drmModeSetCrtc(file_.GetPlatformFile(), crtc_id, 0, 0, 0, NULL, 0,
|
| - NULL);
|
| -}
|
| -
|
| -ScopedDrmConnectorPtr DriWrapper::GetConnector(uint32_t connector_id) {
|
| - DCHECK(file_.IsValid());
|
| - TRACE_EVENT1("dri", "DriWrapper::GetConnector", "connector", connector_id);
|
| - return ScopedDrmConnectorPtr(
|
| - drmModeGetConnector(file_.GetPlatformFile(), connector_id));
|
| -}
|
| -
|
| -bool DriWrapper::AddFramebuffer(uint32_t width,
|
| - uint32_t height,
|
| - uint8_t depth,
|
| - uint8_t bpp,
|
| - uint32_t stride,
|
| - uint32_t handle,
|
| - uint32_t* framebuffer) {
|
| - DCHECK(file_.IsValid());
|
| - TRACE_EVENT1("dri", "DriWrapper::AddFramebuffer",
|
| - "handle", handle);
|
| - return !drmModeAddFB(file_.GetPlatformFile(), width, height, depth, bpp,
|
| - stride, handle, framebuffer);
|
| -}
|
| -
|
| -bool DriWrapper::RemoveFramebuffer(uint32_t framebuffer) {
|
| - DCHECK(file_.IsValid());
|
| - TRACE_EVENT1("dri", "DriWrapper::RemoveFramebuffer",
|
| - "framebuffer", framebuffer);
|
| - return !drmModeRmFB(file_.GetPlatformFile(), framebuffer);
|
| -}
|
| -
|
| -bool DriWrapper::PageFlip(uint32_t crtc_id,
|
| - uint32_t framebuffer,
|
| - bool is_sync,
|
| - const PageFlipCallback& callback) {
|
| - DCHECK(file_.IsValid());
|
| - TRACE_EVENT2("dri", "DriWrapper::PageFlip",
|
| - "crtc", crtc_id,
|
| - "framebuffer", framebuffer);
|
| -
|
| - if (watcher_)
|
| - watcher_->SetPaused(is_sync);
|
| -
|
| - // NOTE: Calling drmModeSetCrtc will immediately update the state, though
|
| - // callbacks to already scheduled page flips will be honored by the kernel.
|
| - scoped_ptr<PageFlipPayload> payload(
|
| - new PageFlipPayload(base::ThreadTaskRunnerHandle::Get(), callback));
|
| - if (!drmModePageFlip(file_.GetPlatformFile(), crtc_id, framebuffer,
|
| - DRM_MODE_PAGE_FLIP_EVENT, payload.get())) {
|
| - // If successful the payload will be removed by a PageFlip event.
|
| - ignore_result(payload.release());
|
| -
|
| - // If the flip was requested synchronous or if no watcher has been installed
|
| - // yet, then synchronously handle the page flip events.
|
| - if (is_sync || !watcher_) {
|
| - TRACE_EVENT1("dri", "OnDrmEvent", "socket", file_.GetPlatformFile());
|
| -
|
| - drmEventContext event;
|
| - event.version = DRM_EVENT_CONTEXT_VERSION;
|
| - event.page_flip_handler = HandlePageFlipEventOnUI;
|
| - event.vblank_handler = nullptr;
|
| -
|
| - drmHandleEvent(file_.GetPlatformFile(), &event);
|
| - }
|
| -
|
| - return true;
|
| - }
|
| -
|
| - return false;
|
| -}
|
| -
|
| -bool DriWrapper::PageFlipOverlay(uint32_t crtc_id,
|
| - uint32_t framebuffer,
|
| - const gfx::Rect& location,
|
| - const gfx::Rect& source,
|
| - int overlay_plane) {
|
| - DCHECK(file_.IsValid());
|
| - TRACE_EVENT2("dri", "DriWrapper::PageFlipOverlay",
|
| - "crtc", crtc_id,
|
| - "framebuffer", framebuffer);
|
| - return !drmModeSetPlane(file_.GetPlatformFile(), overlay_plane, crtc_id,
|
| - framebuffer, 0, location.x(), location.y(),
|
| - location.width(), location.height(), source.x(),
|
| - source.y(), source.width(), source.height());
|
| -}
|
| -
|
| -ScopedDrmFramebufferPtr DriWrapper::GetFramebuffer(uint32_t framebuffer) {
|
| - DCHECK(file_.IsValid());
|
| - TRACE_EVENT1("dri", "DriWrapper::GetFramebuffer",
|
| - "framebuffer", framebuffer);
|
| - return ScopedDrmFramebufferPtr(
|
| - drmModeGetFB(file_.GetPlatformFile(), framebuffer));
|
| -}
|
| -
|
| -ScopedDrmPropertyPtr DriWrapper::GetProperty(drmModeConnector* connector,
|
| - const char* name) {
|
| - TRACE_EVENT2("dri", "DriWrapper::GetProperty",
|
| - "connector", connector->connector_id,
|
| - "name", name);
|
| - for (int i = 0; i < connector->count_props; ++i) {
|
| - ScopedDrmPropertyPtr property(
|
| - drmModeGetProperty(file_.GetPlatformFile(), connector->props[i]));
|
| - if (!property)
|
| - continue;
|
| -
|
| - if (strcmp(property->name, name) == 0)
|
| - return property.Pass();
|
| - }
|
| -
|
| - return ScopedDrmPropertyPtr();
|
| -}
|
| -
|
| -bool DriWrapper::SetProperty(uint32_t connector_id,
|
| - uint32_t property_id,
|
| - uint64_t value) {
|
| - DCHECK(file_.IsValid());
|
| - return !drmModeConnectorSetProperty(file_.GetPlatformFile(), connector_id,
|
| - property_id, value);
|
| -}
|
| -
|
| -bool DriWrapper::GetCapability(uint64_t capability, uint64_t* value) {
|
| - DCHECK(file_.IsValid());
|
| - return !drmGetCap(file_.GetPlatformFile(), capability, value);
|
| -}
|
| -
|
| -ScopedDrmPropertyBlobPtr DriWrapper::GetPropertyBlob(
|
| - drmModeConnector* connector, const char* name) {
|
| - DCHECK(file_.IsValid());
|
| - TRACE_EVENT2("dri", "DriWrapper::GetPropertyBlob",
|
| - "connector", connector->connector_id,
|
| - "name", name);
|
| - for (int i = 0; i < connector->count_props; ++i) {
|
| - ScopedDrmPropertyPtr property(
|
| - drmModeGetProperty(file_.GetPlatformFile(), connector->props[i]));
|
| - if (!property)
|
| - continue;
|
| -
|
| - if (strcmp(property->name, name) == 0 &&
|
| - property->flags & DRM_MODE_PROP_BLOB)
|
| - return ScopedDrmPropertyBlobPtr(drmModeGetPropertyBlob(
|
| - file_.GetPlatformFile(), connector->prop_values[i]));
|
| - }
|
| -
|
| - return ScopedDrmPropertyBlobPtr();
|
| -}
|
| -
|
| -bool DriWrapper::SetCursor(uint32_t crtc_id,
|
| - uint32_t handle,
|
| - const gfx::Size& size) {
|
| - DCHECK(file_.IsValid());
|
| - TRACE_EVENT1("dri", "DriWrapper::SetCursor", "handle", handle);
|
| - return !drmModeSetCursor(file_.GetPlatformFile(), crtc_id, handle,
|
| - size.width(), size.height());
|
| -}
|
| -
|
| -bool DriWrapper::MoveCursor(uint32_t crtc_id, const gfx::Point& point) {
|
| - DCHECK(file_.IsValid());
|
| - return !drmModeMoveCursor(file_.GetPlatformFile(), crtc_id, point.x(),
|
| - point.y());
|
| -}
|
| -
|
| -bool DriWrapper::CreateDumbBuffer(const SkImageInfo& info,
|
| - uint32_t* handle,
|
| - uint32_t* stride,
|
| - void** pixels) {
|
| - DCHECK(file_.IsValid());
|
| -
|
| - TRACE_EVENT0("dri", "DriWrapper::CreateDumbBuffer");
|
| - if (!DrmCreateDumbBuffer(file_.GetPlatformFile(), info, handle, stride))
|
| - return false;
|
| -
|
| - if (!MapDumbBuffer(file_.GetPlatformFile(), *handle,
|
| - info.getSafeSize(*stride), pixels)) {
|
| - DrmDestroyDumbBuffer(file_.GetPlatformFile(), *handle);
|
| - return false;
|
| - }
|
| -
|
| - return true;
|
| -}
|
| -
|
| -void DriWrapper::DestroyDumbBuffer(const SkImageInfo& info,
|
| - uint32_t handle,
|
| - uint32_t stride,
|
| - void* pixels) {
|
| - DCHECK(file_.IsValid());
|
| - TRACE_EVENT1("dri", "DriWrapper::DestroyDumbBuffer", "handle", handle);
|
| - munmap(pixels, info.getSafeSize(stride));
|
| - DrmDestroyDumbBuffer(file_.GetPlatformFile(), handle);
|
| -}
|
| -
|
| -bool DriWrapper::SetMaster() {
|
| - DCHECK(file_.IsValid());
|
| - return (drmSetMaster(file_.GetPlatformFile()) == 0);
|
| -}
|
| -
|
| -bool DriWrapper::DropMaster() {
|
| - DCHECK(file_.IsValid());
|
| - return (drmDropMaster(file_.GetPlatformFile()) == 0);
|
| -}
|
| -
|
| -} // namespace ui
|
|
|