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 |