Index: services/ui/demo/mus_demo.cc |
diff --git a/services/ui/demo/mus_demo.cc b/services/ui/demo/mus_demo.cc |
index d0a90bb18c92594888f24daa5ac617983b20fe12..b73ae2758c703b933ab5ef2c7aa698005bcc176a 100644 |
--- a/services/ui/demo/mus_demo.cc |
+++ b/services/ui/demo/mus_demo.cc |
@@ -4,6 +4,7 @@ |
#include "services/ui/demo/mus_demo.h" |
+#include "base/command_line.h" |
#include "base/memory/ptr_util.h" |
#include "base/time/time.h" |
#include "services/service_manager/public/cpp/connector.h" |
@@ -12,6 +13,7 @@ |
#include "services/ui/public/cpp/gpu/gpu_service.h" |
#include "services/ui/public/cpp/window.h" |
#include "services/ui/public/cpp/window_tree_client.h" |
+#include "services/ui/public/cpp/window_tree_host_factory.h" |
#include "third_party/skia/include/core/SkCanvas.h" |
#include "third_party/skia/include/core/SkColor.h" |
#include "third_party/skia/include/core/SkImageInfo.h" |
@@ -58,8 +60,39 @@ void DrawSquare(const gfx::Rect& bounds, double angle, SkCanvas* canvas) { |
canvas->drawRect(rect, paint); |
} |
+SkBitmap AllocBitmap(Window* window) { |
+ const gfx::Rect bounds = window->GetBoundsInRoot(); |
+ |
+ // Allocate bitmap the same size as the window for drawing. |
+ SkImageInfo image_info = SkImageInfo::MakeN32(bounds.width(), bounds.height(), |
+ kPremul_SkAlphaType); |
+ SkBitmap bitmap; |
+ bitmap.allocPixels(image_info); |
+ return bitmap; |
+} |
+ |
} // namespace |
+struct MusDemo::WindowTreeData { |
+ mojom::WindowTreeHostPtr host; |
+ |
+ std::unique_ptr<WindowTreeClient> window_tree; |
+ |
+ Window* window = nullptr; |
+ |
+ // Used to send frames to mus. |
+ std::unique_ptr<BitmapUploader> uploader; |
+ |
+ // Bitmap that is the same size as our client window area. |
+ SkBitmap bitmap; |
+ |
+ // Current rotation angle for drawing. |
+ double angle = 0.0; |
+ |
+ // Timer for calling DrawFrame(). |
+ base::RepeatingTimer timer; |
+}; |
+ |
MusDemo::MusDemo() {} |
MusDemo::~MusDemo() { |
@@ -67,11 +100,22 @@ MusDemo::~MusDemo() { |
} |
void MusDemo::OnStart() { |
+ external_window_mode_ = |
+ base::CommandLine::ForCurrentProcess()->HasSwitch("external-window-mode"); |
screen_ = base::MakeUnique<display::ScreenBase>(); |
display::Screen::SetScreenInstance(screen_.get()); |
gpu_service_ = GpuService::Create(context()->connector()); |
- window_tree_client_ = base::MakeUnique<WindowTreeClient>(this, this); |
- window_tree_client_->ConnectAsWindowManager(context()->connector()); |
+ if (external_window_mode_) { |
+ // Demonstrates drawing to 2 native windows. |
+ AddWindowTreeHost(); |
+ AddWindowTreeHost(); |
+ } else { |
+ std::unique_ptr<WindowTreeData> data = base::MakeUnique<WindowTreeData>(); |
+ |
+ data->window_tree = base::MakeUnique<WindowTreeClient>(this, this); |
+ data->window_tree->ConnectAsWindowManager(context()->connector()); |
+ window_tree_datas_.push_back(std::move(data)); |
+ } |
} |
bool MusDemo::OnConnect(const service_manager::ServiceInfo& remote_info, |
@@ -80,19 +124,14 @@ bool MusDemo::OnConnect(const service_manager::ServiceInfo& remote_info, |
} |
void MusDemo::OnEmbed(Window* window) { |
- // Not called for the WindowManager. |
- NOTREACHED(); |
+ DCHECK(external_window_mode_); |
+ BeginDrawingFrames(window); |
} |
-void MusDemo::OnEmbedRootDestroyed(Window* root) { |
- // Not called for the WindowManager. |
- NOTREACHED(); |
-} |
+void MusDemo::OnEmbedRootDestroyed(Window* root) {} |
void MusDemo::OnLostConnection(WindowTreeClient* client) { |
- window_ = nullptr; |
- window_tree_client_.reset(); |
- timer_.Stop(); |
+ window_tree_datas_.clear(); |
} |
void MusDemo::OnPointerEventObserved(const PointerEvent& event, |
@@ -122,17 +161,8 @@ void MusDemo::OnWmClientJankinessChanged( |
} |
void MusDemo::OnWmNewDisplay(Window* window, const display::Display& display) { |
- DCHECK(!window_); // Only support one display. |
- window_ = window; |
- |
- // Initialize bitmap uploader for sending frames to MUS. |
- uploader_.reset(new BitmapUploader(window_)); |
- uploader_->Init(gpu_service_.get()); |
- |
- // Draw initial frame and start the timer to regularly draw frames. |
- DrawFrame(); |
- timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(kFrameDelay), |
- base::Bind(&MusDemo::DrawFrame, base::Unretained(this))); |
+ DCHECK(!external_window_mode_); |
+ BeginDrawingFrames(window); |
} |
void MusDemo::OnWmDisplayRemoved(ui::Window* window) { |
@@ -150,52 +180,65 @@ void MusDemo::OnWmPerformMoveLoop(Window* window, |
void MusDemo::OnWmCancelMoveLoop(Window* window) {} |
-void MusDemo::AllocBitmap() { |
- const gfx::Rect bounds = window_->GetBoundsInRoot(); |
- |
- // Allocate bitmap the same size as the window for drawing. |
- bitmap_.reset(); |
- SkImageInfo image_info = SkImageInfo::MakeN32(bounds.width(), bounds.height(), |
- kPremul_SkAlphaType); |
- bitmap_.allocPixels(image_info); |
+void MusDemo::AddWindowTreeHost() { |
+ std::unique_ptr<WindowTreeData> data = base::MakeUnique<WindowTreeData>(); |
+ data->window_tree = |
+ CreateWindowTreeHost(context()->connector(), this, &data->host, nullptr); |
+ window_tree_datas_.push_back(std::move(data)); |
} |
-void MusDemo::DrawFrame() { |
- base::TimeTicks now = base::TimeTicks::Now(); |
+void MusDemo::BeginDrawingFrames(Window* window) { |
+ auto it = |
+ std::find_if(window_tree_datas_.begin(), window_tree_datas_.end(), |
+ [window](std::unique_ptr<WindowTreeData>& data) { |
+ return data->window_tree.get() == window->window_tree(); |
+ }); |
+ DCHECK(it != window_tree_datas_.end()); |
+ auto& data = *it; |
+ |
+ data->window = window; |
- VLOG(1) << (now - last_draw_frame_time_).InMilliseconds() |
- << "ms since the last frame was drawn."; |
- last_draw_frame_time_ = now; |
+ // Initialize bitmap uploader for sending frames to MUS. |
+ data->uploader.reset(new BitmapUploader(window)); |
+ data->uploader->Init(gpu_service_.get()); |
+ |
+ // Draw initial frame and start the timer to regularly draw frames. |
+ DrawFrame(data.get()); |
+ data->timer.Start( |
+ FROM_HERE, base::TimeDelta::FromMilliseconds(kFrameDelay), |
+ base::Bind(&MusDemo::DrawFrame, base::Unretained(this), data.get())); |
+} |
- angle_ += 2.0; |
- if (angle_ >= 360.0) |
- angle_ = 0.0; |
+void MusDemo::DrawFrame(WindowTreeData* data) { |
+ data->angle += 2.0; |
+ if (data->angle >= 360.0) |
+ data->angle = 0.0; |
- const gfx::Rect bounds = window_->GetBoundsInRoot(); |
+ const gfx::Rect bounds = data->window->GetBoundsInRoot(); |
// Check that bitmap and window sizes match, otherwise reallocate bitmap. |
- const SkImageInfo info = bitmap_.info(); |
- if (info.width() != bounds.width() || info.height() != bounds.height()) { |
- AllocBitmap(); |
- } |
+ const SkImageInfo info = data->bitmap.info(); |
+ if (info.width() != bounds.width() || info.height() != bounds.height()) |
+ data->bitmap = AllocBitmap(data->window); |
// Draw the rotated square on background in bitmap. |
- SkCanvas canvas(bitmap_); |
+ SkCanvas canvas(data->bitmap); |
canvas.clear(kBgColor); |
- // TODO(kylechar): Add GL drawing instead of software rasterization in future. |
- DrawSquare(bounds, angle_, &canvas); |
+ // TODO(kylechar): Add GL drawing instead of software rasterization in |
+ // future. |
+ DrawSquare(bounds, data->angle, &canvas); |
canvas.flush(); |
// Copy pixels data into vector that will be passed to BitmapUploader. |
// TODO(rjkroege): Make a 1/0-copy bitmap uploader for the contents of a |
// SkBitmap. |
- bitmap_.lockPixels(); |
+ data->bitmap.lockPixels(); |
const unsigned char* addr = |
- static_cast<const unsigned char*>(bitmap_.getPixels()); |
+ static_cast<const unsigned char*>(data->bitmap.getPixels()); |
const int bytes = bounds.width() * bounds.height() * 4; |
- std::unique_ptr<std::vector<unsigned char>> data( |
+ std::unique_ptr<std::vector<unsigned char>> pixels( |
new std::vector<unsigned char>(addr, addr + bytes)); |
- bitmap_.unlockPixels(); |
+ data->bitmap.unlockPixels(); |
#if defined(OS_ANDROID) |
// TODO(jcivelli): find a way to not have an ifdef here. |
@@ -205,8 +248,8 @@ void MusDemo::DrawFrame() { |
#endif |
// Send frame to MUS via BitmapUploader. |
- uploader_->SetBitmap(bounds.width(), bounds.height(), std::move(data), |
- bitmap_format); |
+ data->uploader->SetBitmap(bounds.width(), bounds.height(), std::move(pixels), |
+ bitmap_format); |
} |
} // namespace demo |