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

Side by Side Diff: services/ui/demo/mus_demo.cc

Issue 2503923003: Demonstrate external-window-mode in mus-demo (Closed)
Patch Set: Determine external window mode in mus-ws based on if a WM is connected Created 4 years, 1 month 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
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 "services/ui/demo/mus_demo.h" 5 #include "services/ui/demo/mus_demo.h"
6 6
7 #include "base/command_line.h"
7 #include "base/memory/ptr_util.h" 8 #include "base/memory/ptr_util.h"
8 #include "base/time/time.h" 9 #include "base/time/time.h"
9 #include "services/service_manager/public/cpp/connector.h" 10 #include "services/service_manager/public/cpp/connector.h"
10 #include "services/service_manager/public/cpp/service_context.h" 11 #include "services/service_manager/public/cpp/service_context.h"
11 #include "services/ui/demo/bitmap_uploader.h" 12 #include "services/ui/demo/bitmap_uploader.h"
12 #include "services/ui/public/cpp/gpu/gpu_service.h" 13 #include "services/ui/public/cpp/gpu/gpu_service.h"
13 #include "services/ui/public/cpp/window.h" 14 #include "services/ui/public/cpp/window.h"
14 #include "services/ui/public/cpp/window_tree_client.h" 15 #include "services/ui/public/cpp/window_tree_client.h"
16 #include "services/ui/public/cpp/window_tree_host_factory.h"
15 #include "third_party/skia/include/core/SkCanvas.h" 17 #include "third_party/skia/include/core/SkCanvas.h"
16 #include "third_party/skia/include/core/SkColor.h" 18 #include "third_party/skia/include/core/SkColor.h"
17 #include "third_party/skia/include/core/SkImageInfo.h" 19 #include "third_party/skia/include/core/SkImageInfo.h"
18 #include "third_party/skia/include/core/SkPaint.h" 20 #include "third_party/skia/include/core/SkPaint.h"
19 #include "third_party/skia/include/core/SkRect.h" 21 #include "third_party/skia/include/core/SkRect.h"
20 #include "ui/gfx/geometry/rect.h" 22 #include "ui/gfx/geometry/rect.h"
23 #include "ui/ozone/public/ozone_switches.h"
21 24
22 namespace ui { 25 namespace ui {
23 namespace demo { 26 namespace demo {
24 27
25 namespace { 28 namespace {
26 29
27 // Milliseconds between frames. 30 // Milliseconds between frames.
28 const int64_t kFrameDelay = 33; 31 const int64_t kFrameDelay = 33;
29 32
30 // Size of square in pixels to draw. 33 // Size of square in pixels to draw.
(...skipping 20 matching lines...) Expand all
51 canvas->translate(SkFloatToScalar(canvas_size.width() * 0.5f), 54 canvas->translate(SkFloatToScalar(canvas_size.width() * 0.5f),
52 SkFloatToScalar(canvas_size.height() * 0.5f)); 55 SkFloatToScalar(canvas_size.height() * 0.5f));
53 canvas->rotate(angle); 56 canvas->rotate(angle);
54 canvas->translate(-SkFloatToScalar(canvas_size.width() * 0.5f), 57 canvas->translate(-SkFloatToScalar(canvas_size.width() * 0.5f),
55 -SkFloatToScalar(canvas_size.height() * 0.5f)); 58 -SkFloatToScalar(canvas_size.height() * 0.5f));
56 } 59 }
57 60
58 canvas->drawRect(rect, paint); 61 canvas->drawRect(rect, paint);
59 } 62 }
60 63
64 SkBitmap AllocBitmap(Window* window) {
65 const gfx::Rect bounds = window->GetBoundsInRoot();
66
67 // Allocate bitmap the same size as the window for drawing.
68 SkImageInfo image_info = SkImageInfo::MakeN32(bounds.width(), bounds.height(),
69 kPremul_SkAlphaType);
70 SkBitmap bitmap;
71 bitmap.allocPixels(image_info);
72 return bitmap;
73 }
74
61 } // namespace 75 } // namespace
62 76
77 struct MusDemo::WindowTreeData {
78 mojom::WindowTreeHostPtr host;
79
80 std::unique_ptr<WindowTreeClient> window_tree;
81
82 Window* window = nullptr;
83
84 // Used to send frames to mus.
85 std::unique_ptr<BitmapUploader> uploader;
86
87 // Bitmap that is the same size as our client window area.
88 SkBitmap bitmap;
89
90 // Current rotation angle for drawing.
91 double angle = 0.0;
92
93 // Timer for calling DrawFrame().
94 base::RepeatingTimer timer;
95 };
96
63 MusDemo::MusDemo() {} 97 MusDemo::MusDemo() {}
64 98
65 MusDemo::~MusDemo() { 99 MusDemo::~MusDemo() {
66 display::Screen::SetScreenInstance(nullptr); 100 display::Screen::SetScreenInstance(nullptr);
67 } 101 }
68 102
69 void MusDemo::OnStart() { 103 void MusDemo::OnStart() {
104 external_window_mode_ = base::CommandLine::ForCurrentProcess()->HasSwitch(
105 switches::kExternalWindowMode);
70 screen_ = base::MakeUnique<display::ScreenBase>(); 106 screen_ = base::MakeUnique<display::ScreenBase>();
71 display::Screen::SetScreenInstance(screen_.get()); 107 display::Screen::SetScreenInstance(screen_.get());
72 gpu_service_ = GpuService::Create(context()->connector()); 108 gpu_service_ = GpuService::Create(context()->connector());
73 window_tree_client_ = base::MakeUnique<WindowTreeClient>(this, this); 109 if (external_window_mode_) {
74 window_tree_client_->ConnectAsWindowManager(context()->connector()); 110 // Demonstrates drawing to 2 native windows.
111 AddWindowTreeHost();
112 AddWindowTreeHost();
113 } else {
114 std::unique_ptr<WindowTreeData> data = base::MakeUnique<WindowTreeData>();
115
116 data->window_tree = base::MakeUnique<WindowTreeClient>(this, this);
117 data->window_tree->ConnectAsWindowManager(context()->connector());
118 window_tree_datas_.push_back(std::move(data));
119 }
75 } 120 }
76 121
77 bool MusDemo::OnConnect(const service_manager::ServiceInfo& remote_info, 122 bool MusDemo::OnConnect(const service_manager::ServiceInfo& remote_info,
78 service_manager::InterfaceRegistry* registry) { 123 service_manager::InterfaceRegistry* registry) {
79 return true; 124 return true;
80 } 125 }
81 126
82 void MusDemo::OnEmbed(Window* window) { 127 void MusDemo::OnEmbed(Window* window) {
83 // Not called for the WindowManager. 128 DCHECK(external_window_mode_);
84 NOTREACHED(); 129 BeginDrawingFrames(window);
85 } 130 }
86 131
87 void MusDemo::OnEmbedRootDestroyed(Window* root) { 132 void MusDemo::OnEmbedRootDestroyed(Window* root) {}
88 // Not called for the WindowManager.
89 NOTREACHED();
90 }
91 133
92 void MusDemo::OnLostConnection(WindowTreeClient* client) { 134 void MusDemo::OnLostConnection(WindowTreeClient* client) {
93 window_ = nullptr; 135 window_tree_datas_.clear();
94 window_tree_client_.reset();
95 timer_.Stop();
96 } 136 }
97 137
98 void MusDemo::OnPointerEventObserved(const PointerEvent& event, 138 void MusDemo::OnPointerEventObserved(const PointerEvent& event,
99 Window* target) {} 139 Window* target) {}
100 140
101 void MusDemo::SetWindowManagerClient(WindowManagerClient* client) {} 141 void MusDemo::SetWindowManagerClient(WindowManagerClient* client) {}
102 142
103 bool MusDemo::OnWmSetBounds(Window* window, gfx::Rect* bounds) { 143 bool MusDemo::OnWmSetBounds(Window* window, gfx::Rect* bounds) {
104 return true; 144 return true;
105 } 145 }
106 146
107 bool MusDemo::OnWmSetProperty(Window* window, 147 bool MusDemo::OnWmSetProperty(Window* window,
108 const std::string& name, 148 const std::string& name,
109 std::unique_ptr<std::vector<uint8_t>>* new_data) { 149 std::unique_ptr<std::vector<uint8_t>>* new_data) {
110 return true; 150 return true;
111 } 151 }
112 152
113 Window* MusDemo::OnWmCreateTopLevelWindow( 153 Window* MusDemo::OnWmCreateTopLevelWindow(
114 std::map<std::string, std::vector<uint8_t>>* properties) { 154 std::map<std::string, std::vector<uint8_t>>* properties) {
115 return nullptr; 155 return nullptr;
116 } 156 }
117 157
118 void MusDemo::OnWmClientJankinessChanged( 158 void MusDemo::OnWmClientJankinessChanged(
119 const std::set<Window*>& client_windows, 159 const std::set<Window*>& client_windows,
120 bool janky) { 160 bool janky) {
121 // Don't care 161 // Don't care
122 } 162 }
123 163
124 void MusDemo::OnWmNewDisplay(Window* window, const display::Display& display) { 164 void MusDemo::OnWmNewDisplay(Window* window, const display::Display& display) {
125 DCHECK(!window_); // Only support one display. 165 DCHECK(!external_window_mode_);
126 window_ = window; 166 BeginDrawingFrames(window);
127
128 // Initialize bitmap uploader for sending frames to MUS.
129 uploader_.reset(new BitmapUploader(window_));
130 uploader_->Init(gpu_service_.get());
131
132 // Draw initial frame and start the timer to regularly draw frames.
133 DrawFrame();
134 timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(kFrameDelay),
135 base::Bind(&MusDemo::DrawFrame, base::Unretained(this)));
136 } 167 }
137 168
138 void MusDemo::OnWmDisplayRemoved(ui::Window* window) { 169 void MusDemo::OnWmDisplayRemoved(ui::Window* window) {
139 window->Destroy(); 170 window->Destroy();
140 } 171 }
141 172
142 void MusDemo::OnWmDisplayModified(const display::Display& display) {} 173 void MusDemo::OnWmDisplayModified(const display::Display& display) {}
143 174
144 void MusDemo::OnWmPerformMoveLoop(Window* window, 175 void MusDemo::OnWmPerformMoveLoop(Window* window,
145 mojom::MoveLoopSource source, 176 mojom::MoveLoopSource source,
146 const gfx::Point& cursor_location, 177 const gfx::Point& cursor_location,
147 const base::Callback<void(bool)>& on_done) { 178 const base::Callback<void(bool)>& on_done) {
148 // Don't care 179 // Don't care
149 } 180 }
150 181
151 void MusDemo::OnWmCancelMoveLoop(Window* window) {} 182 void MusDemo::OnWmCancelMoveLoop(Window* window) {}
152 183
153 void MusDemo::AllocBitmap() { 184 void MusDemo::AddWindowTreeHost() {
154 const gfx::Rect bounds = window_->GetBoundsInRoot(); 185 std::unique_ptr<WindowTreeData> data = base::MakeUnique<WindowTreeData>();
155 186 data->window_tree =
156 // Allocate bitmap the same size as the window for drawing. 187 CreateWindowTreeHost(context()->connector(), this, &data->host, nullptr);
157 bitmap_.reset(); 188 window_tree_datas_.push_back(std::move(data));
158 SkImageInfo image_info = SkImageInfo::MakeN32(bounds.width(), bounds.height(),
159 kPremul_SkAlphaType);
160 bitmap_.allocPixels(image_info);
161 } 189 }
162 190
163 void MusDemo::DrawFrame() { 191 void MusDemo::BeginDrawingFrames(Window* window) {
164 base::TimeTicks now = base::TimeTicks::Now(); 192 auto it =
193 std::find_if(window_tree_datas_.begin(), window_tree_datas_.end(),
194 [window](std::unique_ptr<WindowTreeData>& data) {
195 return data->window_tree.get() == window->window_tree();
196 });
197 DCHECK(it != window_tree_datas_.end());
198 auto& data = *it;
165 199
166 VLOG(1) << (now - last_draw_frame_time_).InMilliseconds() 200 data->window = window;
167 << "ms since the last frame was drawn.";
168 last_draw_frame_time_ = now;
169 201
170 angle_ += 2.0; 202 // Initialize bitmap uploader for sending frames to MUS.
171 if (angle_ >= 360.0) 203 data->uploader.reset(new BitmapUploader(window));
172 angle_ = 0.0; 204 data->uploader->Init(gpu_service_.get());
173 205
174 const gfx::Rect bounds = window_->GetBoundsInRoot(); 206 // Draw initial frame and start the timer to regularly draw frames.
207 DrawFrame(data.get());
208 data->timer.Start(
209 FROM_HERE, base::TimeDelta::FromMilliseconds(kFrameDelay),
210 base::Bind(&MusDemo::DrawFrame, base::Unretained(this), data.get()));
211 }
212
213 void MusDemo::DrawFrame(WindowTreeData* data) {
214 data->angle += 2.0;
215 if (data->angle >= 360.0)
216 data->angle = 0.0;
217
218 const gfx::Rect bounds = data->window->GetBoundsInRoot();
175 219
176 // Check that bitmap and window sizes match, otherwise reallocate bitmap. 220 // Check that bitmap and window sizes match, otherwise reallocate bitmap.
177 const SkImageInfo info = bitmap_.info(); 221 const SkImageInfo info = data->bitmap.info();
178 if (info.width() != bounds.width() || info.height() != bounds.height()) { 222 if (info.width() != bounds.width() || info.height() != bounds.height())
179 AllocBitmap(); 223 data->bitmap = AllocBitmap(data->window);
180 }
181 224
182 // Draw the rotated square on background in bitmap. 225 // Draw the rotated square on background in bitmap.
183 SkCanvas canvas(bitmap_); 226 SkCanvas canvas(data->bitmap);
184 canvas.clear(kBgColor); 227 canvas.clear(kBgColor);
185 // TODO(kylechar): Add GL drawing instead of software rasterization in future. 228 // TODO(kylechar): Add GL drawing instead of software rasterization in
186 DrawSquare(bounds, angle_, &canvas); 229 // future.
230 DrawSquare(bounds, data->angle, &canvas);
187 canvas.flush(); 231 canvas.flush();
188 232
189 // Copy pixels data into vector that will be passed to BitmapUploader. 233 // Copy pixels data into vector that will be passed to BitmapUploader.
190 // TODO(rjkroege): Make a 1/0-copy bitmap uploader for the contents of a 234 // TODO(rjkroege): Make a 1/0-copy bitmap uploader for the contents of a
191 // SkBitmap. 235 // SkBitmap.
192 bitmap_.lockPixels(); 236 data->bitmap.lockPixels();
193 const unsigned char* addr = 237 const unsigned char* addr =
194 static_cast<const unsigned char*>(bitmap_.getPixels()); 238 static_cast<const unsigned char*>(data->bitmap.getPixels());
195 const int bytes = bounds.width() * bounds.height() * 4; 239 const int bytes = bounds.width() * bounds.height() * 4;
196 std::unique_ptr<std::vector<unsigned char>> data( 240 std::unique_ptr<std::vector<unsigned char>> pixels(
197 new std::vector<unsigned char>(addr, addr + bytes)); 241 new std::vector<unsigned char>(addr, addr + bytes));
198 bitmap_.unlockPixels(); 242 data->bitmap.unlockPixels();
199 243
200 #if defined(OS_ANDROID) 244 #if defined(OS_ANDROID)
201 // TODO(jcivelli): find a way to not have an ifdef here. 245 // TODO(jcivelli): find a way to not have an ifdef here.
202 BitmapUploader::Format bitmap_format = BitmapUploader::RGBA; 246 BitmapUploader::Format bitmap_format = BitmapUploader::RGBA;
203 #else 247 #else
204 BitmapUploader::Format bitmap_format = BitmapUploader::BGRA; 248 BitmapUploader::Format bitmap_format = BitmapUploader::BGRA;
205 #endif 249 #endif
206 250
207 // Send frame to MUS via BitmapUploader. 251 // Send frame to MUS via BitmapUploader.
208 uploader_->SetBitmap(bounds.width(), bounds.height(), std::move(data), 252 data->uploader->SetBitmap(bounds.width(), bounds.height(), std::move(pixels),
209 bitmap_format); 253 bitmap_format);
210 } 254 }
211 255
212 } // namespace demo 256 } // namespace demo
213 } // namespace ui 257 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698