Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(158)

Side by Side Diff: ui/ozone/platform/drm/gpu/drm_window.cc

Issue 1285183008: Ozone integration. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: add missing license header Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "ui/ozone/platform/drm/gpu/drm_window.h"
6
7 #include "base/trace_event/trace_event.h"
8 #include "third_party/skia/include/core/SkBitmap.h"
9 #include "third_party/skia/include/core/SkDevice.h"
10 #include "third_party/skia/include/core/SkSurface.h"
11 #include "ui/ozone/common/gpu/ozone_gpu_message_params.h"
12 #include "ui/ozone/platform/drm/gpu/drm_buffer.h"
13 #include "ui/ozone/platform/drm/gpu/drm_device.h"
14 #include "ui/ozone/platform/drm/gpu/drm_device_manager.h"
15 #include "ui/ozone/platform/drm/gpu/scanout_buffer.h"
16 #include "ui/ozone/platform/drm/gpu/screen_manager.h"
17
18 namespace ui {
19
20 namespace {
21
22 #ifndef DRM_CAP_CURSOR_WIDTH
23 #define DRM_CAP_CURSOR_WIDTH 0x8
24 #endif
25
26 #ifndef DRM_CAP_CURSOR_HEIGHT
27 #define DRM_CAP_CURSOR_HEIGHT 0x9
28 #endif
29
30 void EmptyFlipCallback(gfx::SwapResult) {
31 }
32
33 void UpdateCursorImage(DrmBuffer* cursor, const SkBitmap& image) {
34 SkRect damage;
35 image.getBounds(&damage);
36
37 // Clear to transparent in case |image| is smaller than the canvas.
38 SkCanvas* canvas = cursor->GetCanvas();
39 canvas->clear(SK_ColorTRANSPARENT);
40
41 SkRect clip;
42 clip.set(0, 0, canvas->getDeviceSize().width(),
43 canvas->getDeviceSize().height());
44 canvas->clipRect(clip, SkRegion::kReplace_Op);
45 canvas->drawBitmapRectToRect(image, &damage, damage);
46 }
47
48 } // namespace
49
50 DrmWindow::DrmWindow(gfx::AcceleratedWidget widget,
51 DrmDeviceManager* device_manager,
52 ScreenManager* screen_manager)
53 : widget_(widget),
54 device_manager_(device_manager),
55 screen_manager_(screen_manager) {
56 }
57
58 DrmWindow::~DrmWindow() {
59 }
60
61 void DrmWindow::Initialize() {
62 TRACE_EVENT1("drm", "DrmWindow::Initialize", "widget", widget_);
63
64 device_manager_->UpdateDrmDevice(widget_, nullptr);
65 }
66
67 void DrmWindow::Shutdown() {
68 TRACE_EVENT1("drm", "DrmWindow::Shutdown", "widget", widget_);
69 device_manager_->RemoveDrmDevice(widget_);
70 }
71
72 gfx::AcceleratedWidget DrmWindow::GetAcceleratedWidget() {
73 return widget_;
74 }
75
76 HardwareDisplayController* DrmWindow::GetController() {
77 return controller_;
78 }
79
80 void DrmWindow::OnBoundsChanged(const gfx::Rect& bounds) {
81 TRACE_EVENT2("drm", "DrmWindow::OnBoundsChanged", "widget", widget_, "bounds",
82 bounds.ToString());
83 bounds_ = bounds;
84 if (bounds_.size() != bounds.size())
85 last_submitted_planes_.clear();
86
87 screen_manager_->UpdateControllerToWindowMapping();
88 }
89
90 void DrmWindow::SetCursor(const std::vector<SkBitmap>& bitmaps,
91 const gfx::Point& location,
92 int frame_delay_ms) {
93 cursor_bitmaps_ = bitmaps;
94 cursor_location_ = location;
95 cursor_frame_ = 0;
96 cursor_frame_delay_ms_ = frame_delay_ms;
97 cursor_timer_.Stop();
98
99 if (cursor_frame_delay_ms_)
100 cursor_timer_.Start(
101 FROM_HERE, base::TimeDelta::FromMilliseconds(cursor_frame_delay_ms_),
102 this, &DrmWindow::OnCursorAnimationTimeout);
103
104 ResetCursor(false);
105 }
106
107 void DrmWindow::SetCursorWithoutAnimations(const std::vector<SkBitmap>& bitmaps,
108 const gfx::Point& location) {
109 cursor_bitmaps_ = bitmaps;
110 cursor_location_ = location;
111 cursor_frame_ = 0;
112 cursor_frame_delay_ms_ = 0;
113 ResetCursor(false);
114 }
115
116 void DrmWindow::MoveCursor(const gfx::Point& location) {
117 cursor_location_ = location;
118
119 if (controller_)
120 controller_->MoveCursor(location);
121 }
122
123 void DrmWindow::QueueOverlayPlane(const OverlayPlane& plane) {
124 pending_planes_.push_back(plane);
125 }
126
127 bool DrmWindow::SchedulePageFlip(bool is_sync,
128 const SwapCompletionCallback& callback) {
129 last_submitted_planes_.clear();
130 last_submitted_planes_.swap(pending_planes_);
131 last_swap_sync_ = is_sync;
132
133 if (controller_) {
134 return controller_->SchedulePageFlip(last_submitted_planes_, is_sync, false,
135 callback);
136 }
137
138 callback.Run(gfx::SwapResult::SWAP_ACK);
139 return true;
140 }
141
142 bool DrmWindow::TestPageFlip(const std::vector<OverlayCheck_Params>& overlays,
143 ScanoutBufferGenerator* buffer_generator) {
144 if (!controller_)
145 return true;
146 for (const auto& overlay : overlays) {
147 // It is possible that the cc rect we get actually falls off the edge of
148 // the screen. Usually this is prevented via things like status bars
149 // blocking overlaying or cc clipping it, but in case it wasn't properly
150 // clipped (since GL will render this situation fine) just ignore it here.
151 // This should be an extremely rare occurrance.
152 if (overlay.plane_z_order != 0 && !bounds().Contains(overlay.display_rect))
153 return false;
154 }
155
156 scoped_refptr<DrmDevice> drm = controller_->GetAllocationDrmDevice();
157 OverlayPlaneList planes;
158 for (const auto& overlay : overlays) {
159 gfx::Size size =
160 (overlay.plane_z_order == 0) ? bounds().size() : overlay.buffer_size;
161 scoped_refptr<ScanoutBuffer> buffer = buffer_generator->Create(drm, size);
162 if (!buffer)
163 return false;
164 planes.push_back(OverlayPlane(buffer, overlay.plane_z_order,
165 overlay.transform, overlay.display_rect,
166 gfx::RectF(gfx::Size(1, 1))));
167 }
168 return controller_->SchedulePageFlip(planes, true, true,
169 base::Bind(&EmptyFlipCallback));
170 }
171
172 const OverlayPlane* DrmWindow::GetLastModesetBuffer() {
173 return OverlayPlane::GetPrimaryPlane(last_submitted_planes_);
174 }
175
176 void DrmWindow::ResetCursor(bool bitmap_only) {
177 if (!controller_)
178 return;
179
180 if (cursor_bitmaps_.size()) {
181 // Draw new cursor into backbuffer.
182 UpdateCursorImage(cursor_buffers_[cursor_frontbuffer_ ^ 1].get(),
183 cursor_bitmaps_[cursor_frame_]);
184
185 // Reset location & buffer.
186 if (!bitmap_only)
187 controller_->MoveCursor(cursor_location_);
188 controller_->SetCursor(cursor_buffers_[cursor_frontbuffer_ ^ 1]);
189 cursor_frontbuffer_ ^= 1;
190 } else {
191 // No cursor set.
192 controller_->UnsetCursor();
193 }
194 }
195
196 void DrmWindow::OnCursorAnimationTimeout() {
197 cursor_frame_++;
198 cursor_frame_ %= cursor_bitmaps_.size();
199
200 ResetCursor(true);
201 }
202
203 void DrmWindow::SetController(HardwareDisplayController* controller) {
204 if (controller_ == controller)
205 return;
206
207 controller_ = controller;
208 device_manager_->UpdateDrmDevice(
209 widget_, controller ? controller->GetAllocationDrmDevice() : nullptr);
210
211 UpdateCursorBuffers();
212 // We changed displays, so we want to update the cursor as well.
213 ResetCursor(false /* bitmap_only */);
214 }
215
216 void DrmWindow::UpdateCursorBuffers() {
217 if (!controller_) {
218 for (size_t i = 0; i < arraysize(cursor_buffers_); ++i) {
219 cursor_buffers_[i] = nullptr;
220 }
221 } else {
222 scoped_refptr<DrmDevice> drm = controller_->GetAllocationDrmDevice();
223
224 uint64_t cursor_width = 64;
225 uint64_t cursor_height = 64;
226 drm->GetCapability(DRM_CAP_CURSOR_WIDTH, &cursor_width);
227 drm->GetCapability(DRM_CAP_CURSOR_HEIGHT, &cursor_height);
228
229 SkImageInfo info = SkImageInfo::MakeN32Premul(cursor_width, cursor_height);
230 for (size_t i = 0; i < arraysize(cursor_buffers_); ++i) {
231 cursor_buffers_[i] = new DrmBuffer(drm);
232 // Don't register a framebuffer for cursors since they are special (they
233 // aren't modesetting buffers and drivers may fail to register them due to
234 // their small sizes).
235 if (!cursor_buffers_[i]->Initialize(
236 info, false /* should_register_framebuffer */)) {
237 LOG(FATAL) << "Failed to initialize cursor buffer";
238 return;
239 }
240 }
241 }
242 }
243
244 } // namespace ui
OLDNEW
« no previous file with comments | « ui/ozone/platform/drm/gpu/drm_window.h ('k') | ui/ozone/platform/drm/gpu/drm_window_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698