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

Unified 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 side-by-side diff with in-line comments
Download patch
« 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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/ozone/platform/drm/gpu/drm_window.cc
diff --git a/ui/ozone/platform/drm/gpu/drm_window.cc b/ui/ozone/platform/drm/gpu/drm_window.cc
new file mode 100644
index 0000000000000000000000000000000000000000..3dda06cd307395763a54f9b96b38705affbeab7a
--- /dev/null
+++ b/ui/ozone/platform/drm/gpu/drm_window.cc
@@ -0,0 +1,244 @@
+// 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/drm_window.h"
+
+#include "base/trace_event/trace_event.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+#include "third_party/skia/include/core/SkDevice.h"
+#include "third_party/skia/include/core/SkSurface.h"
+#include "ui/ozone/common/gpu/ozone_gpu_message_params.h"
+#include "ui/ozone/platform/drm/gpu/drm_buffer.h"
+#include "ui/ozone/platform/drm/gpu/drm_device.h"
+#include "ui/ozone/platform/drm/gpu/drm_device_manager.h"
+#include "ui/ozone/platform/drm/gpu/scanout_buffer.h"
+#include "ui/ozone/platform/drm/gpu/screen_manager.h"
+
+namespace ui {
+
+namespace {
+
+#ifndef DRM_CAP_CURSOR_WIDTH
+#define DRM_CAP_CURSOR_WIDTH 0x8
+#endif
+
+#ifndef DRM_CAP_CURSOR_HEIGHT
+#define DRM_CAP_CURSOR_HEIGHT 0x9
+#endif
+
+void EmptyFlipCallback(gfx::SwapResult) {
+}
+
+void UpdateCursorImage(DrmBuffer* cursor, const SkBitmap& image) {
+ SkRect damage;
+ image.getBounds(&damage);
+
+ // Clear to transparent in case |image| is smaller than the canvas.
+ SkCanvas* canvas = cursor->GetCanvas();
+ canvas->clear(SK_ColorTRANSPARENT);
+
+ SkRect clip;
+ clip.set(0, 0, canvas->getDeviceSize().width(),
+ canvas->getDeviceSize().height());
+ canvas->clipRect(clip, SkRegion::kReplace_Op);
+ canvas->drawBitmapRectToRect(image, &damage, damage);
+}
+
+} // namespace
+
+DrmWindow::DrmWindow(gfx::AcceleratedWidget widget,
+ DrmDeviceManager* device_manager,
+ ScreenManager* screen_manager)
+ : widget_(widget),
+ device_manager_(device_manager),
+ screen_manager_(screen_manager) {
+}
+
+DrmWindow::~DrmWindow() {
+}
+
+void DrmWindow::Initialize() {
+ TRACE_EVENT1("drm", "DrmWindow::Initialize", "widget", widget_);
+
+ device_manager_->UpdateDrmDevice(widget_, nullptr);
+}
+
+void DrmWindow::Shutdown() {
+ TRACE_EVENT1("drm", "DrmWindow::Shutdown", "widget", widget_);
+ device_manager_->RemoveDrmDevice(widget_);
+}
+
+gfx::AcceleratedWidget DrmWindow::GetAcceleratedWidget() {
+ return widget_;
+}
+
+HardwareDisplayController* DrmWindow::GetController() {
+ return controller_;
+}
+
+void DrmWindow::OnBoundsChanged(const gfx::Rect& bounds) {
+ TRACE_EVENT2("drm", "DrmWindow::OnBoundsChanged", "widget", widget_, "bounds",
+ bounds.ToString());
+ bounds_ = bounds;
+ if (bounds_.size() != bounds.size())
+ last_submitted_planes_.clear();
+
+ screen_manager_->UpdateControllerToWindowMapping();
+}
+
+void DrmWindow::SetCursor(const std::vector<SkBitmap>& bitmaps,
+ const gfx::Point& location,
+ int frame_delay_ms) {
+ cursor_bitmaps_ = bitmaps;
+ cursor_location_ = location;
+ cursor_frame_ = 0;
+ cursor_frame_delay_ms_ = frame_delay_ms;
+ cursor_timer_.Stop();
+
+ if (cursor_frame_delay_ms_)
+ cursor_timer_.Start(
+ FROM_HERE, base::TimeDelta::FromMilliseconds(cursor_frame_delay_ms_),
+ this, &DrmWindow::OnCursorAnimationTimeout);
+
+ ResetCursor(false);
+}
+
+void DrmWindow::SetCursorWithoutAnimations(const std::vector<SkBitmap>& bitmaps,
+ const gfx::Point& location) {
+ cursor_bitmaps_ = bitmaps;
+ cursor_location_ = location;
+ cursor_frame_ = 0;
+ cursor_frame_delay_ms_ = 0;
+ ResetCursor(false);
+}
+
+void DrmWindow::MoveCursor(const gfx::Point& location) {
+ cursor_location_ = location;
+
+ if (controller_)
+ controller_->MoveCursor(location);
+}
+
+void DrmWindow::QueueOverlayPlane(const OverlayPlane& plane) {
+ pending_planes_.push_back(plane);
+}
+
+bool DrmWindow::SchedulePageFlip(bool is_sync,
+ const SwapCompletionCallback& callback) {
+ last_submitted_planes_.clear();
+ last_submitted_planes_.swap(pending_planes_);
+ last_swap_sync_ = is_sync;
+
+ if (controller_) {
+ return controller_->SchedulePageFlip(last_submitted_planes_, is_sync, false,
+ callback);
+ }
+
+ callback.Run(gfx::SwapResult::SWAP_ACK);
+ return true;
+}
+
+bool DrmWindow::TestPageFlip(const std::vector<OverlayCheck_Params>& overlays,
+ ScanoutBufferGenerator* buffer_generator) {
+ if (!controller_)
+ return true;
+ for (const auto& overlay : overlays) {
+ // It is possible that the cc rect we get actually falls off the edge of
+ // the screen. Usually this is prevented via things like status bars
+ // blocking overlaying or cc clipping it, but in case it wasn't properly
+ // clipped (since GL will render this situation fine) just ignore it here.
+ // This should be an extremely rare occurrance.
+ if (overlay.plane_z_order != 0 && !bounds().Contains(overlay.display_rect))
+ return false;
+ }
+
+ scoped_refptr<DrmDevice> drm = controller_->GetAllocationDrmDevice();
+ OverlayPlaneList planes;
+ for (const auto& overlay : overlays) {
+ gfx::Size size =
+ (overlay.plane_z_order == 0) ? bounds().size() : overlay.buffer_size;
+ scoped_refptr<ScanoutBuffer> buffer = buffer_generator->Create(drm, size);
+ if (!buffer)
+ return false;
+ planes.push_back(OverlayPlane(buffer, overlay.plane_z_order,
+ overlay.transform, overlay.display_rect,
+ gfx::RectF(gfx::Size(1, 1))));
+ }
+ return controller_->SchedulePageFlip(planes, true, true,
+ base::Bind(&EmptyFlipCallback));
+}
+
+const OverlayPlane* DrmWindow::GetLastModesetBuffer() {
+ return OverlayPlane::GetPrimaryPlane(last_submitted_planes_);
+}
+
+void DrmWindow::ResetCursor(bool bitmap_only) {
+ if (!controller_)
+ return;
+
+ if (cursor_bitmaps_.size()) {
+ // Draw new cursor into backbuffer.
+ UpdateCursorImage(cursor_buffers_[cursor_frontbuffer_ ^ 1].get(),
+ cursor_bitmaps_[cursor_frame_]);
+
+ // Reset location & buffer.
+ if (!bitmap_only)
+ controller_->MoveCursor(cursor_location_);
+ controller_->SetCursor(cursor_buffers_[cursor_frontbuffer_ ^ 1]);
+ cursor_frontbuffer_ ^= 1;
+ } else {
+ // No cursor set.
+ controller_->UnsetCursor();
+ }
+}
+
+void DrmWindow::OnCursorAnimationTimeout() {
+ cursor_frame_++;
+ cursor_frame_ %= cursor_bitmaps_.size();
+
+ ResetCursor(true);
+}
+
+void DrmWindow::SetController(HardwareDisplayController* controller) {
+ if (controller_ == controller)
+ return;
+
+ controller_ = controller;
+ device_manager_->UpdateDrmDevice(
+ widget_, controller ? controller->GetAllocationDrmDevice() : nullptr);
+
+ UpdateCursorBuffers();
+ // We changed displays, so we want to update the cursor as well.
+ ResetCursor(false /* bitmap_only */);
+}
+
+void DrmWindow::UpdateCursorBuffers() {
+ if (!controller_) {
+ for (size_t i = 0; i < arraysize(cursor_buffers_); ++i) {
+ cursor_buffers_[i] = nullptr;
+ }
+ } else {
+ scoped_refptr<DrmDevice> drm = controller_->GetAllocationDrmDevice();
+
+ uint64_t cursor_width = 64;
+ uint64_t cursor_height = 64;
+ drm->GetCapability(DRM_CAP_CURSOR_WIDTH, &cursor_width);
+ drm->GetCapability(DRM_CAP_CURSOR_HEIGHT, &cursor_height);
+
+ SkImageInfo info = SkImageInfo::MakeN32Premul(cursor_width, cursor_height);
+ for (size_t i = 0; i < arraysize(cursor_buffers_); ++i) {
+ cursor_buffers_[i] = new DrmBuffer(drm);
+ // Don't register a framebuffer for cursors since they are special (they
+ // aren't modesetting buffers and drivers may fail to register them due to
+ // their small sizes).
+ if (!cursor_buffers_[i]->Initialize(
+ info, false /* should_register_framebuffer */)) {
+ LOG(FATAL) << "Failed to initialize cursor buffer";
+ return;
+ }
+ }
+ }
+}
+
+} // namespace ui
« 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