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.
5 #include "ui/ozone/platform/dri/dri_surface_factory.h"
9 #include "base/debug/trace_event.h"
10 #include "third_party/skia/include/core/SkBitmap.h"
11 #include "third_party/skia/include/core/SkDevice.h"
12 #include "third_party/skia/include/core/SkSurface.h"
13 #include "ui/gfx/native_widget_types.h"
14 #include "ui/ozone/platform/dri/dri_buffer.h"
15 #include "ui/ozone/platform/dri/dri_surface.h"
16 #include "ui/ozone/platform/dri/dri_util.h"
17 #include "ui/ozone/platform/dri/dri_window_delegate_impl.h"
18 #include "ui/ozone/platform/dri/dri_window_delegate_manager.h"
19 #include "ui/ozone/platform/dri/dri_wrapper.h"
20 #include "ui/ozone/platform/dri/hardware_display_controller.h"
21 #include "ui/ozone/platform/dri/screen_manager.h"
22 #include "ui/ozone/public/surface_ozone_canvas.h"
28 // TODO(dnicoara) Read the cursor plane size from the hardware.
29 const gfx::Size kCursorSize(64, 64);
31 void UpdateCursorImage(DriBuffer* cursor, const SkBitmap& image) {
33 image.getBounds(&damage);
35 // Clear to transparent in case |image| is smaller than the canvas.
36 SkCanvas* canvas = cursor->GetCanvas();
37 canvas->clear(SK_ColorTRANSPARENT);
41 0, 0, canvas->getDeviceSize().width(), canvas->getDeviceSize().height());
42 canvas->clipRect(clip, SkRegion::kReplace_Op);
43 canvas->drawBitmapRectToRect(image, &damage, damage);
49 const gfx::AcceleratedWidget DriSurfaceFactory::kDefaultWidgetHandle = 1;
51 DriSurfaceFactory::DriSurfaceFactory(DriWrapper* drm,
52 ScreenManager* screen_manager,
53 DriWindowDelegateManager* window_manager)
55 screen_manager_(screen_manager),
56 window_manager_(window_manager),
57 state_(UNINITIALIZED),
58 cursor_frontbuffer_(0),
61 cursor_frame_delay_ms_(0) {
64 DriSurfaceFactory::~DriSurfaceFactory() {
65 if (state_ == INITIALIZED)
69 DriSurfaceFactory::HardwareState DriSurfaceFactory::InitializeHardware() {
70 if (state_ != UNINITIALIZED)
73 if (drm_->get_fd() < 0) {
74 LOG(ERROR) << "Failed to create DRI connection";
79 SkImageInfo info = SkImageInfo::MakeN32Premul(kCursorSize.width(),
80 kCursorSize.height());
81 for (size_t i = 0; i < arraysize(cursor_buffers_); ++i) {
82 cursor_buffers_[i] = new DriBuffer(drm_);
83 if (!cursor_buffers_[i]->Initialize(info)) {
84 LOG(ERROR) << "Failed to initialize cursor buffer";
94 void DriSurfaceFactory::ShutdownHardware() {
95 DCHECK(state_ == INITIALIZED);
96 state_ = UNINITIALIZED;
99 scoped_ptr<ui::SurfaceOzoneCanvas> DriSurfaceFactory::CreateCanvasForWidget(
100 gfx::AcceleratedWidget widget) {
101 DCHECK(state_ == INITIALIZED);
103 return scoped_ptr<ui::SurfaceOzoneCanvas>(
104 new DriSurface(window_manager_->GetWindowDelegate(widget), drm_));
107 bool DriSurfaceFactory::LoadEGLGLES2Bindings(
108 AddGLLibraryCallback add_gl_library,
109 SetGLGetProcAddressProcCallback set_gl_get_proc_address) {
113 void DriSurfaceFactory::SetHardwareCursor(gfx::AcceleratedWidget widget,
114 const std::vector<SkBitmap>& bitmaps,
115 const gfx::Point& location,
116 int frame_delay_ms) {
117 cursor_widget_ = widget;
118 cursor_bitmaps_ = bitmaps;
119 cursor_location_ = location;
121 cursor_frame_delay_ms_ = frame_delay_ms;
122 cursor_timer_.Stop();
124 if (cursor_frame_delay_ms_)
127 base::TimeDelta::FromMilliseconds(cursor_frame_delay_ms_),
129 &DriSurfaceFactory::OnCursorAnimationTimeout);
131 if (state_ != INITIALIZED)
137 void DriSurfaceFactory::MoveHardwareCursor(gfx::AcceleratedWidget widget,
138 const gfx::Point& location) {
139 cursor_location_ = location;
141 if (state_ != INITIALIZED)
144 HardwareDisplayController* controller =
145 window_manager_->GetWindowDelegate(widget)->GetController();
147 controller->MoveCursor(location);
150 ////////////////////////////////////////////////////////////////////////////////
151 // DriSurfaceFactory private
153 void DriSurfaceFactory::ResetCursor() {
157 HardwareDisplayController* controller =
158 window_manager_->GetWindowDelegate(cursor_widget_)->GetController();
159 if (cursor_bitmaps_.size()) {
160 // Draw new cursor into backbuffer.
161 UpdateCursorImage(cursor_buffers_[cursor_frontbuffer_ ^ 1].get(),
162 cursor_bitmaps_[cursor_frame_]);
164 // Reset location & buffer.
166 controller->MoveCursor(cursor_location_);
167 controller->SetCursor(cursor_buffers_[cursor_frontbuffer_ ^ 1]);
168 cursor_frontbuffer_ ^= 1;
173 controller->UnsetCursor();
177 void DriSurfaceFactory::OnCursorAnimationTimeout() {
179 cursor_frame_ %= cursor_bitmaps_.size();