summaryrefslogtreecommitdiffstats
path: root/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.cc
blob: 1fcc7ca2821c9e6137f897dc2886977a60ce77e5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
// 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/drm/gpu/hardware_display_plane_manager_atomic.h"

#include "base/bind.h"
#include "ui/ozone/platform/drm/gpu/crtc_controller.h"
#include "ui/ozone/platform/drm/gpu/drm_device.h"
#include "ui/ozone/platform/drm/gpu/hardware_display_plane_atomic.h"
#include "ui/ozone/platform/drm/gpu/scanout_buffer.h"

namespace ui {

static void AtomicPageFlipCallback(
    std::vector<base::WeakPtr<CrtcController>> crtcs,
    unsigned int frame,
    unsigned int seconds,
    unsigned int useconds) {
  for (auto& crtc : crtcs) {
    auto* crtc_ptr = crtc.get();
    if (crtc_ptr)
      crtc_ptr->OnPageFlipEvent(frame, seconds, useconds);
  }
}

HardwareDisplayPlaneManagerAtomic::HardwareDisplayPlaneManagerAtomic() {
}

HardwareDisplayPlaneManagerAtomic::~HardwareDisplayPlaneManagerAtomic() {
}

bool HardwareDisplayPlaneManagerAtomic::Commit(
    HardwareDisplayPlaneList* plane_list,
    bool is_sync,
    bool test_only) {
  for (HardwareDisplayPlane* plane : plane_list->old_plane_list) {
    bool found =
        std::find(plane_list->plane_list.begin(), plane_list->plane_list.end(),
                  plane) != plane_list->plane_list.end();
    if (!found) {
      // This plane is being released, so we need to zero it.
      plane->set_in_use(false);
      HardwareDisplayPlaneAtomic* atomic_plane =
          static_cast<HardwareDisplayPlaneAtomic*>(plane);
      atomic_plane->SetPlaneData(plane_list->atomic_property_set.get(), 0, 0,
                                 gfx::Rect(), gfx::Rect());
    }
  }

  std::vector<base::WeakPtr<CrtcController>> crtcs;
  for (HardwareDisplayPlane* plane : plane_list->plane_list) {
    HardwareDisplayPlaneAtomic* atomic_plane =
        static_cast<HardwareDisplayPlaneAtomic*>(plane);
    if (crtcs.empty() || crtcs.back().get() != atomic_plane->crtc())
      crtcs.push_back(atomic_plane->crtc()->AsWeakPtr());
  }

  if (test_only) {
    for (HardwareDisplayPlane* plane : plane_list->plane_list) {
      plane->set_in_use(false);
    }
  } else {
    plane_list->plane_list.swap(plane_list->old_plane_list);
  }
  plane_list->plane_list.clear();
  if (!drm_->CommitProperties(plane_list->atomic_property_set.get(), 0, is_sync,
                              test_only, base::Bind(&AtomicPageFlipCallback))) {
    PLOG(ERROR) << "Failed to commit properties";
    return false;
  }
  return true;
}

bool HardwareDisplayPlaneManagerAtomic::SetPlaneData(
    HardwareDisplayPlaneList* plane_list,
    HardwareDisplayPlane* hw_plane,
    const OverlayPlane& overlay,
    uint32_t crtc_id,
    const gfx::Rect& src_rect,
    CrtcController* crtc) {
  HardwareDisplayPlaneAtomic* atomic_plane =
      static_cast<HardwareDisplayPlaneAtomic*>(hw_plane);
  if (!atomic_plane->SetPlaneData(plane_list->atomic_property_set.get(),
                                  crtc_id, overlay.buffer->GetFramebufferId(),
                                  overlay.display_bounds, src_rect)) {
    LOG(ERROR) << "Failed to set plane properties";
    return false;
  }
  atomic_plane->set_crtc(crtc);
  return true;
}

scoped_ptr<HardwareDisplayPlane> HardwareDisplayPlaneManagerAtomic::CreatePlane(
    uint32_t plane_id,
    uint32_t possible_crtcs) {
  return scoped_ptr<HardwareDisplayPlane>(
      new HardwareDisplayPlaneAtomic(plane_id, possible_crtcs));
}

}  // namespace ui