summaryrefslogtreecommitdiffstats
path: root/mojo/services/native_viewport/native_viewport_impl.cc
diff options
context:
space:
mode:
Diffstat (limited to 'mojo/services/native_viewport/native_viewport_impl.cc')
-rw-r--r--mojo/services/native_viewport/native_viewport_impl.cc138
1 files changed, 138 insertions, 0 deletions
diff --git a/mojo/services/native_viewport/native_viewport_impl.cc b/mojo/services/native_viewport/native_viewport_impl.cc
new file mode 100644
index 0000000..8755dfd
--- /dev/null
+++ b/mojo/services/native_viewport/native_viewport_impl.cc
@@ -0,0 +1,138 @@
+// Copyright 2014 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 "mojo/services/native_viewport/native_viewport_impl.h"
+
+#include "base/macros.h"
+#include "base/message_loop/message_loop.h"
+#include "base/time/time.h"
+#include "mojo/public/cpp/application/application_delegate.h"
+#include "mojo/public/cpp/application/interface_factory.h"
+#include "mojo/services/public/cpp/geometry/geometry_type_converters.h"
+#include "mojo/services/public/cpp/input_events/input_events_type_converters.h"
+#include "ui/events/event.h"
+
+namespace mojo {
+namespace {
+
+bool IsRateLimitedEventType(ui::Event* event) {
+ return event->type() == ui::ET_MOUSE_MOVED ||
+ event->type() == ui::ET_MOUSE_DRAGGED ||
+ event->type() == ui::ET_TOUCH_MOVED;
+}
+
+} // namespace
+
+NativeViewportImpl::NativeViewportImpl()
+ : widget_(gfx::kNullAcceleratedWidget),
+ waiting_for_event_ack_(false),
+ weak_factory_(this) {}
+
+NativeViewportImpl::~NativeViewportImpl() {
+ // 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 NativeViewportImpl::Create(RectPtr bounds) {
+ platform_viewport_ = PlatformViewport::Create(this);
+ platform_viewport_->Init(bounds.To<gfx::Rect>());
+ client()->OnCreated();
+ OnBoundsChanged(bounds.To<gfx::Rect>());
+}
+
+void NativeViewportImpl::Show() {
+ platform_viewport_->Show();
+}
+
+void NativeViewportImpl::Hide() {
+ platform_viewport_->Hide();
+}
+
+void NativeViewportImpl::Close() {
+ command_buffer_.reset();
+ DCHECK(platform_viewport_);
+ platform_viewport_->Close();
+}
+
+void NativeViewportImpl::SetBounds(RectPtr bounds) {
+ platform_viewport_->SetBounds(bounds.To<gfx::Rect>());
+}
+
+void NativeViewportImpl::CreateGLES2Context(
+ InterfaceRequest<CommandBuffer> command_buffer_request) {
+ if (command_buffer_ || command_buffer_request_.is_pending()) {
+ LOG(ERROR) << "Can't create multiple contexts on a NativeViewport";
+ return;
+ }
+ command_buffer_request_ = command_buffer_request.Pass();
+ CreateCommandBufferIfNeeded();
+}
+
+void NativeViewportImpl::OnBoundsChanged(const gfx::Rect& bounds) {
+ CreateCommandBufferIfNeeded();
+ client()->OnBoundsChanged(Rect::From(bounds));
+}
+
+void NativeViewportImpl::OnAcceleratedWidgetAvailable(
+ gfx::AcceleratedWidget widget) {
+ widget_ = widget;
+ CreateCommandBufferIfNeeded();
+}
+
+bool NativeViewportImpl::OnEvent(ui::Event* ui_event) {
+ // Must not return early before updating capture.
+ switch (ui_event->type()) {
+ case ui::ET_MOUSE_PRESSED:
+ case ui::ET_TOUCH_PRESSED:
+ platform_viewport_->SetCapture();
+ break;
+ case ui::ET_MOUSE_RELEASED:
+ case ui::ET_TOUCH_RELEASED:
+ platform_viewport_->ReleaseCapture();
+ break;
+ default:
+ break;
+ }
+
+ if (waiting_for_event_ack_ && IsRateLimitedEventType(ui_event))
+ return false;
+
+ client()->OnEvent(
+ TypeConverter<EventPtr, ui::Event>::ConvertFrom(*ui_event),
+ base::Bind(&NativeViewportImpl::AckEvent,
+ weak_factory_.GetWeakPtr()));
+ waiting_for_event_ack_ = true;
+ return false;
+}
+
+void NativeViewportImpl::OnDestroyed() {
+ client()->OnDestroyed(base::Bind(&NativeViewportImpl::AckDestroyed,
+ base::Unretained(this)));
+}
+
+void NativeViewportImpl::AckEvent() {
+ waiting_for_event_ack_ = false;
+}
+
+void NativeViewportImpl::CreateCommandBufferIfNeeded() {
+ if (!command_buffer_request_.is_pending())
+ return;
+ DCHECK(!command_buffer_.get());
+ if (widget_ == gfx::kNullAcceleratedWidget)
+ return;
+ gfx::Size size = platform_viewport_->GetSize();
+ if (size.IsEmpty())
+ return;
+ command_buffer_.reset(
+ new CommandBufferImpl(widget_, platform_viewport_->GetSize()));
+ WeakBindToRequest(command_buffer_.get(), &command_buffer_request_);
+}
+
+void NativeViewportImpl::AckDestroyed() {
+ command_buffer_.reset();
+}
+
+} // namespace mojo
+