Chromium Code Reviews| Index: components/view_manager/native_viewport/native_viewport.cc |
| diff --git a/components/view_manager/native_viewport/native_viewport.cc b/components/view_manager/native_viewport/native_viewport.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..e04b582e150a96ec698529c6c3bed37afa865255 |
| --- /dev/null |
| +++ b/components/view_manager/native_viewport/native_viewport.cc |
| @@ -0,0 +1,157 @@ |
| +// Copyright 2015 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "components/view_manager/native_viewport/native_viewport.h" |
| + |
| +#include "base/bind.h" |
| +#include "components/view_manager/event_dispatcher.h" |
| +#include "components/view_manager/gles2/gpu_state.h" |
| +#include "components/view_manager/native_viewport/platform_viewport_headless.h" |
| +#include "ui/events/event.h" |
| +#include "ui/gfx/geometry/size.h" |
| + |
| +namespace view_manager { |
| + |
| +NativeViewport::NativeViewport( |
| + const gfx::Size& size, |
| + bool is_headless, |
| + const scoped_refptr<gles2::GpuState>& gpu_state, |
| + EventDispatcher* event_dispatcher, |
| + const ViewDestroyedCallback& view_destroyed_callback) |
| + : context_provider_( |
| + new native_viewport::OnscreenContextProvider(gpu_state)), |
| + size_(size), |
| + device_scale_factor_(1.f), |
| + metrics_ready_(false), |
| + event_dispatcher_(event_dispatcher), |
| + view_destroyed_callback_(view_destroyed_callback), |
| + weak_factory_(this) { |
| + if (is_headless) { |
| + platform_viewport_ = |
| + native_viewport::PlatformViewportHeadless::Create(this); |
| + } else { |
| + platform_viewport_ = native_viewport::PlatformViewport::Create(this); |
| + } |
| + platform_viewport_->Init(gfx::Rect(size)); |
| +} |
| + |
| +NativeViewport::~NativeViewport() { |
| + // Destroy before |platform_viewport_| because this will destroy |
| + // CommandBufferDriver objects that contain child windows. Otherwise if this |
| + // class destroys its window first, X errors will occur. |
| + context_provider_.reset(); |
| + |
| + // Destroy the NativeViewport early on as it may call us back during |
| + // destruction and we want to be in a known state. |
| + platform_viewport_.reset(); |
| +} |
| + |
| +void NativeViewport::RequestMetrics( |
| + const RequestMetricsCallback& callback) { |
| + if (metrics_ready_) { |
| + // Make sure we can't re-entrantly call this callback again. |
| + metrics_ready_ = false; |
| + callback.Run(size_, device_scale_factor_); |
| + return; |
| + } |
| + metrics_callback_ = callback; |
| +} |
| + |
| +void NativeViewport::Show() { |
| + platform_viewport_->Show(); |
| +} |
| + |
| +void NativeViewport::Hide() { |
| + platform_viewport_->Hide(); |
| +} |
| + |
| +void NativeViewport::Close() { |
| + DCHECK(platform_viewport_); |
| + platform_viewport_->Close(); |
| +} |
| + |
| +void NativeViewport::SetSize(const gfx::Size& size) { |
| + platform_viewport_->SetBounds(gfx::Rect(size)); |
| +} |
| + |
| +void NativeViewport::GetContextProvider( |
| + mojo::InterfaceRequest<mojo::ContextProvider> request) { |
| + context_provider_->Bind(request.Pass()); |
| +} |
| + |
| +void NativeViewport::OnMetricsChanged(const gfx::Size& size, |
| + float device_scale_factor) { |
| + if (size_ == size && device_scale_factor_ == device_scale_factor) |
| + return; |
| + |
| + size_ = size; |
| + device_scale_factor_ = device_scale_factor; |
| + metrics_ready_ = true; |
| + if (!metrics_callback_.is_null()) { |
| + metrics_ready_ = false; |
| + metrics_callback_.Run(size_, device_scale_factor_); |
| + // TODO(fsamuel): calling the callback can reentrantly change the |
| + // metrics_callback. |
| + //metrics_callback_.reset(); |
| + } |
| +} |
| + |
| +void NativeViewport::OnAcceleratedWidgetAvailable( |
| + gfx::AcceleratedWidget widget, |
| + float device_pixel_ratio) { |
| + context_provider_->SetAcceleratedWidget(widget); |
| + // TODO: The metrics here might not match the actual window size on android |
| + // where we don't know the actual size until the first OnMetricsChanged call. |
| + OnMetricsChanged(size_, device_pixel_ratio); |
| +} |
| + |
| +void NativeViewport::OnAcceleratedWidgetDestroyed() { |
| + context_provider_->SetAcceleratedWidget(gfx::kNullAcceleratedWidget); |
| +} |
| + |
| +bool NativeViewport::OnEvent(mojo::EventPtr event) { |
| + if (event.is_null() || !event_dispatcher_) |
| + return false; |
| + |
| + mojo::Callback<void()> callback; |
|
sky
2015/06/04 22:37:58
Alot of this code can be cleaned up too.
Fady Samuel
2015/06/05 22:14:31
Done.
|
| + switch (event->action) { |
| + case mojo::EVENT_TYPE_POINTER_MOVE: { |
| + // TODO(sky): add logic to remember last event location and not send if |
| + // the same. |
| + if (pointers_waiting_on_ack_.count(event->pointer_data->pointer_id)) |
| + return false; |
| + |
| + pointers_waiting_on_ack_.insert(event->pointer_data->pointer_id); |
| + callback = |
| + base::Bind(&NativeViewport::AckEvent, weak_factory_.GetWeakPtr(), |
| + event->pointer_data->pointer_id); |
| + break; |
| + } |
| + |
| + case mojo::EVENT_TYPE_POINTER_CANCEL: |
| + pointers_waiting_on_ack_.clear(); |
| + break; |
| + |
| + case mojo::EVENT_TYPE_POINTER_UP: |
| + pointers_waiting_on_ack_.erase(event->pointer_data->pointer_id); |
| + break; |
| + |
| + default: |
| + break; |
| + } |
| + |
| + event_dispatcher_->OnEvent(event.Pass(), callback); |
| + return false; |
| +} |
| + |
| +void NativeViewport::OnDestroyed() { |
| + if (!view_destroyed_callback_.is_null()) |
| + view_destroyed_callback_.Run(); |
| +} |
| + |
| +void NativeViewport::AckEvent(int32 pointer_id) { |
| + pointers_waiting_on_ack_.erase(pointer_id); |
| +} |
| + |
| +} // namespace view_manager |