OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/ozone/platform/dri/dri_surface_factory.h" | 5 #include "ui/ozone/platform/dri/dri_surface_factory.h" |
6 | 6 |
7 #include <errno.h> | 7 #include <errno.h> |
8 | 8 |
9 #include "base/debug/trace_event.h" | 9 #include "base/debug/trace_event.h" |
10 #include "base/message_loop/message_loop.h" | |
11 #include "third_party/skia/include/core/SkBitmap.h" | 10 #include "third_party/skia/include/core/SkBitmap.h" |
12 #include "third_party/skia/include/core/SkDevice.h" | 11 #include "third_party/skia/include/core/SkDevice.h" |
13 #include "third_party/skia/include/core/SkSurface.h" | 12 #include "third_party/skia/include/core/SkSurface.h" |
14 #include "ui/gfx/native_widget_types.h" | 13 #include "ui/gfx/native_widget_types.h" |
15 #include "ui/ozone/platform/dri/dri_buffer.h" | 14 #include "ui/ozone/platform/dri/dri_buffer.h" |
16 #include "ui/ozone/platform/dri/dri_surface.h" | 15 #include "ui/ozone/platform/dri/dri_surface.h" |
17 #include "ui/ozone/platform/dri/dri_util.h" | 16 #include "ui/ozone/platform/dri/dri_util.h" |
18 #include "ui/ozone/platform/dri/dri_vsync_provider.h" | |
19 #include "ui/ozone/platform/dri/dri_wrapper.h" | 17 #include "ui/ozone/platform/dri/dri_wrapper.h" |
20 #include "ui/ozone/platform/dri/hardware_display_controller.h" | 18 #include "ui/ozone/platform/dri/hardware_display_controller.h" |
21 #include "ui/ozone/platform/dri/screen_manager.h" | 19 #include "ui/ozone/platform/dri/screen_manager.h" |
22 #include "ui/ozone/public/surface_ozone_canvas.h" | 20 #include "ui/ozone/public/surface_ozone_canvas.h" |
23 | 21 |
24 namespace ui { | 22 namespace ui { |
25 | 23 |
26 namespace { | 24 namespace { |
27 | 25 |
28 // TODO(dnicoara) Read the cursor plane size from the hardware. | 26 // TODO(dnicoara) Read the cursor plane size from the hardware. |
29 const gfx::Size kCursorSize(64, 64); | 27 const gfx::Size kCursorSize(64, 64); |
30 | 28 |
31 void UpdateCursorImage(DriBuffer* cursor, const SkBitmap& image) { | 29 void UpdateCursorImage(DriBuffer* cursor, const SkBitmap& image) { |
32 SkRect damage; | 30 SkRect damage; |
33 image.getBounds(&damage); | 31 image.getBounds(&damage); |
34 | 32 |
35 // Clear to transparent in case |image| is smaller than the canvas. | 33 // Clear to transparent in case |image| is smaller than the canvas. |
36 SkCanvas* canvas = cursor->GetCanvas(); | 34 SkCanvas* canvas = cursor->GetCanvas(); |
37 canvas->clear(SK_ColorTRANSPARENT); | 35 canvas->clear(SK_ColorTRANSPARENT); |
38 | 36 |
39 SkRect clip; | 37 SkRect clip; |
40 clip.set( | 38 clip.set( |
41 0, 0, canvas->getDeviceSize().width(), canvas->getDeviceSize().height()); | 39 0, 0, canvas->getDeviceSize().width(), canvas->getDeviceSize().height()); |
42 canvas->clipRect(clip, SkRegion::kReplace_Op); | 40 canvas->clipRect(clip, SkRegion::kReplace_Op); |
43 canvas->drawBitmapRectToRect(image, &damage, damage); | 41 canvas->drawBitmapRectToRect(image, &damage, damage); |
44 } | 42 } |
45 | 43 |
46 class DriSurfaceAdapter : public ui::SurfaceOzoneCanvas { | |
47 public: | |
48 DriSurfaceAdapter(DriWrapper* dri, | |
49 const base::WeakPtr<HardwareDisplayController>& controller); | |
50 virtual ~DriSurfaceAdapter(); | |
51 | |
52 // SurfaceOzoneCanvas: | |
53 virtual skia::RefPtr<SkCanvas> GetCanvas() OVERRIDE; | |
54 virtual void ResizeCanvas(const gfx::Size& viewport_size) OVERRIDE; | |
55 virtual void PresentCanvas(const gfx::Rect& damage) OVERRIDE; | |
56 virtual scoped_ptr<gfx::VSyncProvider> CreateVSyncProvider() OVERRIDE; | |
57 | |
58 private: | |
59 void UpdateNativeSurface(const gfx::Rect& damage); | |
60 | |
61 DriWrapper* dri_; | |
62 scoped_ptr<DriSurface> native_surface_; | |
63 skia::RefPtr<SkSurface> surface_; | |
64 gfx::Rect last_damage_; | |
65 base::WeakPtr<HardwareDisplayController> controller_; | |
66 | |
67 DISALLOW_COPY_AND_ASSIGN(DriSurfaceAdapter); | |
68 }; | |
69 | |
70 DriSurfaceAdapter::DriSurfaceAdapter( | |
71 DriWrapper* dri, | |
72 const base::WeakPtr<HardwareDisplayController>& controller) | |
73 : dri_(dri), controller_(controller) { | |
74 } | |
75 | |
76 DriSurfaceAdapter::~DriSurfaceAdapter() { | |
77 } | |
78 | |
79 skia::RefPtr<SkCanvas> DriSurfaceAdapter::GetCanvas() { | |
80 return skia::SharePtr(surface_->getCanvas()); | |
81 } | |
82 | |
83 void DriSurfaceAdapter::ResizeCanvas(const gfx::Size& viewport_size) { | |
84 SkImageInfo info = SkImageInfo::MakeN32( | |
85 viewport_size.width(), viewport_size.height(), kOpaque_SkAlphaType); | |
86 surface_ = skia::AdoptRef(SkSurface::NewRaster(info)); | |
87 | |
88 if (controller_) { | |
89 // Need to use the mode size rather than |viewport_size| since a display | |
90 // cannot scanout from a buffer smaller than the mode. | |
91 native_surface_.reset( | |
92 new DriSurface(dri_, | |
93 gfx::Size(controller_->get_mode().hdisplay, | |
94 controller_->get_mode().vdisplay))); | |
95 CHECK(native_surface_->Initialize()); | |
96 } | |
97 } | |
98 | |
99 void DriSurfaceAdapter::PresentCanvas(const gfx::Rect& damage) { | |
100 CHECK(base::MessageLoopForUI::IsCurrent()); | |
101 if (!controller_) | |
102 return; | |
103 | |
104 UpdateNativeSurface(damage); | |
105 controller_->SchedulePageFlip(std::vector<OverlayPlane>( | |
106 1, OverlayPlane(native_surface_->backbuffer()))); | |
107 controller_->WaitForPageFlipEvent(); | |
108 native_surface_->SwapBuffers(); | |
109 } | |
110 | |
111 scoped_ptr<gfx::VSyncProvider> DriSurfaceAdapter::CreateVSyncProvider() { | |
112 return scoped_ptr<gfx::VSyncProvider>(new DriVSyncProvider(controller_)); | |
113 } | |
114 | |
115 void DriSurfaceAdapter::UpdateNativeSurface(const gfx::Rect& damage) { | |
116 SkCanvas* canvas = native_surface_->GetDrawableForWidget(); | |
117 | |
118 // The DriSurface is double buffered, so the current back buffer is | |
119 // missing the previous update. Expand damage region. | |
120 SkRect real_damage = RectToSkRect(UnionRects(damage, last_damage_)); | |
121 | |
122 // Copy damage region. | |
123 skia::RefPtr<SkImage> image = skia::AdoptRef(surface_->newImageSnapshot()); | |
124 image->draw(canvas, &real_damage, real_damage, NULL); | |
125 | |
126 last_damage_ = damage; | |
127 } | |
128 | |
129 } // namespace | 44 } // namespace |
130 | 45 |
131 // static | 46 // static |
132 const gfx::AcceleratedWidget DriSurfaceFactory::kDefaultWidgetHandle = 1; | 47 const gfx::AcceleratedWidget DriSurfaceFactory::kDefaultWidgetHandle = 1; |
133 | 48 |
134 DriSurfaceFactory::DriSurfaceFactory(DriWrapper* drm, | 49 DriSurfaceFactory::DriSurfaceFactory( |
135 ScreenManager* screen_manager) | 50 DriWrapper* drm, |
| 51 ScreenManager* screen_manager) |
136 : drm_(drm), | 52 : drm_(drm), |
137 screen_manager_(screen_manager), | 53 screen_manager_(screen_manager), |
138 state_(UNINITIALIZED), | 54 state_(UNINITIALIZED), |
139 allocated_widgets_(0), | 55 allocated_widgets_(0), |
140 cursor_frontbuffer_(0) { | 56 cursor_frontbuffer_(0) { |
141 } | 57 } |
142 | 58 |
143 DriSurfaceFactory::~DriSurfaceFactory() { | 59 DriSurfaceFactory::~DriSurfaceFactory() { |
144 if (state_ == INITIALIZED) | 60 if (state_ == INITIALIZED) |
145 ShutdownHardware(); | 61 ShutdownHardware(); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
183 return ++allocated_widgets_; | 99 return ++allocated_widgets_; |
184 } | 100 } |
185 | 101 |
186 scoped_ptr<ui::SurfaceOzoneCanvas> DriSurfaceFactory::CreateCanvasForWidget( | 102 scoped_ptr<ui::SurfaceOzoneCanvas> DriSurfaceFactory::CreateCanvasForWidget( |
187 gfx::AcceleratedWidget w) { | 103 gfx::AcceleratedWidget w) { |
188 CHECK(state_ == INITIALIZED); | 104 CHECK(state_ == INITIALIZED); |
189 // Initial cursor set. | 105 // Initial cursor set. |
190 ResetCursor(w); | 106 ResetCursor(w); |
191 | 107 |
192 return scoped_ptr<ui::SurfaceOzoneCanvas>( | 108 return scoped_ptr<ui::SurfaceOzoneCanvas>( |
193 new DriSurfaceAdapter(drm_, screen_manager_->GetDisplayController(w))); | 109 new DriSurface(drm_, screen_manager_->GetDisplayController(w))); |
194 } | 110 } |
195 | 111 |
196 bool DriSurfaceFactory::LoadEGLGLES2Bindings( | 112 bool DriSurfaceFactory::LoadEGLGLES2Bindings( |
197 AddGLLibraryCallback add_gl_library, | 113 AddGLLibraryCallback add_gl_library, |
198 SetGLGetProcAddressProcCallback set_gl_get_proc_address) { | 114 SetGLGetProcAddressProcCallback set_gl_get_proc_address) { |
199 return false; | 115 return false; |
200 } | 116 } |
201 | 117 |
202 gfx::Size DriSurfaceFactory::GetWidgetSize(gfx::AcceleratedWidget w) { | 118 gfx::Size DriSurfaceFactory::GetWidgetSize(gfx::AcceleratedWidget w) { |
203 base::WeakPtr<HardwareDisplayController> controller = | 119 base::WeakPtr<HardwareDisplayController> controller = |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
253 cursor_frontbuffer_ ^= 1; | 169 cursor_frontbuffer_ ^= 1; |
254 } | 170 } |
255 } else { | 171 } else { |
256 // No cursor set. | 172 // No cursor set. |
257 if (controller) | 173 if (controller) |
258 controller->UnsetCursor(); | 174 controller->UnsetCursor(); |
259 } | 175 } |
260 } | 176 } |
261 | 177 |
262 } // namespace ui | 178 } // namespace ui |
OLD | NEW |