| 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
|
|
|