native_viewport_impl.cc revision a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7
15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// found in the LICENSE file. 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "mojo/services/native_viewport/native_viewport_impl.h" 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "base/message_loop/message_loop.h" 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "base/time/time.h" 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "mojo/services/gles2/gles2_impl.h" 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "mojo/services/native_viewport/native_viewport.h" 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "ui/events/event.h" 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace mojo { 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace services { 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace { 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool IsRateLimitedEventType(ui::Event* event) { 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return event->type() == ui::ET_MOUSE_MOVED || 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) event->type() == ui::ET_MOUSE_DRAGGED || 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) event->type() == ui::ET_TOUCH_MOVED; 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// NativeViewportImpl, public: 275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)NativeViewportImpl::NativeViewportImpl(shell::Context* context, 295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ScopedMessagePipeHandle pipe) 305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) : context_(context), 315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) widget_(gfx::kNullAcceleratedWidget), 325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) waiting_for_event_ack_(false), 335267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) pending_event_timestamp_(0), 345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) client_(pipe.Pass()) { 3509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) client_.SetPeer(this); 3609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)} 375267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) 385267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)NativeViewportImpl::~NativeViewportImpl() { 395267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)} 407757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch 415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 4251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)// NativeViewportImpl, NativeViewportStub overrides: 435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 447242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid NativeViewportImpl::Open() { 455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) native_viewport_ = services::NativeViewport::Create(context_, this); 465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) native_viewport_->Init(); 475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) client_->OnCreated(); 485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void NativeViewportImpl::Close() { 515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DCHECK(native_viewport_); 525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) native_viewport_->Close(); 535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void NativeViewportImpl::CreateGLES2Context( 565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ScopedMessagePipeHandle gles2_client) { 575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) gles2_.reset(new GLES2Impl(gles2_client.Pass())); 585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) CreateGLES2ContextIfNeeded(); 595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void NativeViewportImpl::AckEvent(const Event& event) { 625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DCHECK_EQ(event.time_stamp(), pending_event_timestamp_); 635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) waiting_for_event_ack_ = false; 645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// NativeViewportImpl, NativeViewportDelegate implementation: 685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 69926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void NativeViewportImpl::OnResized(const gfx::Size& size) { 705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 71926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void NativeViewportImpl::OnAcceleratedWidgetAvailable( 735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) gfx::AcceleratedWidget widget) { 745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) widget_ = widget; 755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) CreateGLES2ContextIfNeeded(); 765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool NativeViewportImpl::OnEvent(ui::Event* ui_event) { 7951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) // Must not return early before updating capture. 80 switch (ui_event->type()) { 81 case ui::ET_MOUSE_PRESSED: 82 case ui::ET_TOUCH_PRESSED: 83 native_viewport_->SetCapture(); 84 break; 85 case ui::ET_MOUSE_RELEASED: 86 case ui::ET_TOUCH_RELEASED: 87 native_viewport_->ReleaseCapture(); 88 break; 89 default: 90 break; 91 } 92 93 if (waiting_for_event_ack_ && IsRateLimitedEventType(ui_event)) 94 return false; 95 96 AllocationScope scope; 97 98 Event::Builder event; 99 event.set_action(ui_event->type()); 100 pending_event_timestamp_ = ui_event->time_stamp().ToInternalValue(); 101 event.set_time_stamp(pending_event_timestamp_); 102 103 if (ui_event->IsMouseEvent() || ui_event->IsTouchEvent()) { 104 ui::LocatedEvent* located_event = static_cast<ui::LocatedEvent*>(ui_event); 105 Point::Builder location; 106 location.set_x(located_event->location().x()); 107 location.set_y(located_event->location().y()); 108 event.set_location(location.Finish()); 109 } 110 111 if (ui_event->IsTouchEvent()) { 112 ui::TouchEvent* touch_event = static_cast<ui::TouchEvent*>(ui_event); 113 TouchData::Builder touch_data; 114 touch_data.set_pointer_id(touch_event->touch_id()); 115 event.set_touch_data(touch_data.Finish()); 116 } 117 118 client_->OnEvent(event.Finish()); 119 waiting_for_event_ack_ = true; 120 return false; 121} 122 123void NativeViewportImpl::OnDestroyed() { 124 // TODO(beng): 125 // Destroying |gles2_| on the shell thread here hits thread checker asserts. 126 // All code must stop touching the AcceleratedWidget at this point as it is 127 // dead after this call stack. jamesr said we probably should make our own 128 // GLSurface and simply tell it to stop touching the AcceleratedWidget 129 // via Destroy() but we have no good way of doing that right now given our 130 // current threading model so james' recommendation was just to wait until 131 // after we move the gl service out of process. 132 // gles2_.reset(); 133 client_->OnDestroyed(); 134} 135 136//////////////////////////////////////////////////////////////////////////////// 137// NativeViewportImpl, private: 138 139void NativeViewportImpl::CreateGLES2ContextIfNeeded() { 140 if (widget_ == gfx::kNullAcceleratedWidget || !gles2_) 141 return; 142 gles2_->CreateContext(widget_, native_viewport_->GetSize()); 143} 144 145} // namespace services 146} // namespace mojo 147