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

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

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

Powered by Google App Engine
This is Rietveld 408576698