| OLD | NEW |
| (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/dri/dri_surface_factory.h" | |
| 6 | |
| 7 #include <errno.h> | |
| 8 | |
| 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" | |
| 23 | |
| 24 namespace ui { | |
| 25 | |
| 26 namespace { | |
| 27 | |
| 28 // TODO(dnicoara) Read the cursor plane size from the hardware. | |
| 29 const gfx::Size kCursorSize(64, 64); | |
| 30 | |
| 31 void UpdateCursorImage(DriBuffer* cursor, const SkBitmap& image) { | |
| 32 SkRect damage; | |
| 33 image.getBounds(&damage); | |
| 34 | |
| 35 // Clear to transparent in case |image| is smaller than the canvas. | |
| 36 SkCanvas* canvas = cursor->GetCanvas(); | |
| 37 canvas->clear(SK_ColorTRANSPARENT); | |
| 38 | |
| 39 SkRect clip; | |
| 40 clip.set( | |
| 41 0, 0, canvas->getDeviceSize().width(), canvas->getDeviceSize().height()); | |
| 42 canvas->clipRect(clip, SkRegion::kReplace_Op); | |
| 43 canvas->drawBitmapRectToRect(image, &damage, damage); | |
| 44 } | |
| 45 | |
| 46 } // namespace | |
| 47 | |
| 48 // static | |
| 49 const gfx::AcceleratedWidget DriSurfaceFactory::kDefaultWidgetHandle = 1; | |
| 50 | |
| 51 DriSurfaceFactory::DriSurfaceFactory(DriWrapper* drm, | |
| 52 ScreenManager* screen_manager, | |
| 53 DriWindowDelegateManager* window_manager) | |
| 54 : drm_(drm), | |
| 55 screen_manager_(screen_manager), | |
| 56 window_manager_(window_manager), | |
| 57 state_(UNINITIALIZED), | |
| 58 cursor_frontbuffer_(0), | |
| 59 cursor_widget_(0), | |
| 60 cursor_frame_(0), | |
| 61 cursor_frame_delay_ms_(0) { | |
| 62 } | |
| 63 | |
| 64 DriSurfaceFactory::~DriSurfaceFactory() { | |
| 65 if (state_ == INITIALIZED) | |
| 66 ShutdownHardware(); | |
| 67 } | |
| 68 | |
| 69 DriSurfaceFactory::HardwareState DriSurfaceFactory::InitializeHardware() { | |
| 70 if (state_ != UNINITIALIZED) | |
| 71 return state_; | |
| 72 | |
| 73 if (drm_->get_fd() < 0) { | |
| 74 LOG(ERROR) << "Failed to create DRI connection"; | |
| 75 state_ = FAILED; | |
| 76 return state_; | |
| 77 } | |
| 78 | |
| 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"; | |
| 85 state_ = FAILED; | |
| 86 return state_; | |
| 87 } | |
| 88 } | |
| 89 | |
| 90 state_ = INITIALIZED; | |
| 91 return state_; | |
| 92 } | |
| 93 | |
| 94 void DriSurfaceFactory::ShutdownHardware() { | |
| 95 DCHECK(state_ == INITIALIZED); | |
| 96 state_ = UNINITIALIZED; | |
| 97 } | |
| 98 | |
| 99 scoped_ptr<ui::SurfaceOzoneCanvas> DriSurfaceFactory::CreateCanvasForWidget( | |
| 100 gfx::AcceleratedWidget widget) { | |
| 101 DCHECK(state_ == INITIALIZED); | |
| 102 | |
| 103 return scoped_ptr<ui::SurfaceOzoneCanvas>( | |
| 104 new DriSurface(window_manager_->GetWindowDelegate(widget), drm_)); | |
| 105 } | |
| 106 | |
| 107 bool DriSurfaceFactory::LoadEGLGLES2Bindings( | |
| 108 AddGLLibraryCallback add_gl_library, | |
| 109 SetGLGetProcAddressProcCallback set_gl_get_proc_address) { | |
| 110 return false; | |
| 111 } | |
| 112 | |
| 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; | |
| 120 cursor_frame_ = 0; | |
| 121 cursor_frame_delay_ms_ = frame_delay_ms; | |
| 122 cursor_timer_.Stop(); | |
| 123 | |
| 124 if (cursor_frame_delay_ms_) | |
| 125 cursor_timer_.Start( | |
| 126 FROM_HERE, | |
| 127 base::TimeDelta::FromMilliseconds(cursor_frame_delay_ms_), | |
| 128 this, | |
| 129 &DriSurfaceFactory::OnCursorAnimationTimeout); | |
| 130 | |
| 131 if (state_ != INITIALIZED) | |
| 132 return; | |
| 133 | |
| 134 ResetCursor(); | |
| 135 } | |
| 136 | |
| 137 void DriSurfaceFactory::MoveHardwareCursor(gfx::AcceleratedWidget widget, | |
| 138 const gfx::Point& location) { | |
| 139 cursor_location_ = location; | |
| 140 | |
| 141 if (state_ != INITIALIZED) | |
| 142 return; | |
| 143 | |
| 144 HardwareDisplayController* controller = | |
| 145 window_manager_->GetWindowDelegate(widget)->GetController(); | |
| 146 if (controller) | |
| 147 controller->MoveCursor(location); | |
| 148 } | |
| 149 | |
| 150 //////////////////////////////////////////////////////////////////////////////// | |
| 151 // DriSurfaceFactory private | |
| 152 | |
| 153 void DriSurfaceFactory::ResetCursor() { | |
| 154 if (!cursor_widget_) | |
| 155 return; | |
| 156 | |
| 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_]); | |
| 163 | |
| 164 // Reset location & buffer. | |
| 165 if (controller) { | |
| 166 controller->MoveCursor(cursor_location_); | |
| 167 controller->SetCursor(cursor_buffers_[cursor_frontbuffer_ ^ 1]); | |
| 168 cursor_frontbuffer_ ^= 1; | |
| 169 } | |
| 170 } else { | |
| 171 // No cursor set. | |
| 172 if (controller) | |
| 173 controller->UnsetCursor(); | |
| 174 } | |
| 175 } | |
| 176 | |
| 177 void DriSurfaceFactory::OnCursorAnimationTimeout() { | |
| 178 cursor_frame_++; | |
| 179 cursor_frame_ %= cursor_bitmaps_.size(); | |
| 180 | |
| 181 ResetCursor(); | |
| 182 } | |
| 183 | |
| 184 } // namespace ui | |
| OLD | NEW |