Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "mojo/services/native_viewport/native_viewport_impl.h" | 5 #include "base/memory/scoped_vector.h" |
| 6 | |
| 7 #include "base/message_loop/message_loop.h" | 6 #include "base/message_loop/message_loop.h" |
| 7 #include "mojo/common/bindings_support_impl.h" | |
| 8 #include "mojo/services/gles2/gles2_impl.h" | 8 #include "mojo/services/gles2/gles2_impl.h" |
| 9 #include "mojo/services/native_viewport/native_viewport.h" | 9 #include "mojo/services/native_viewport/native_viewport.h" |
| 10 #include "mojom/native_viewport.h" | |
| 11 #include "mojom/shell.h" | |
| 10 #include "ui/events/event.h" | 12 #include "ui/events/event.h" |
| 11 | 13 |
| 14 #if defined(WIN32) | |
| 15 #if !defined(CDECL) | |
| 16 #define CDECL __cdecl | |
| 17 #endif | |
| 18 #define NATIVE_VIEWPORT_EXPORT __declspec(dllexport) | |
| 19 #else | |
| 20 #define CDECL | |
| 21 #define NATIVE_VIEWPORT_EXPORT __attribute__((visibility("default"))) | |
| 22 #endif | |
| 23 | |
| 12 namespace mojo { | 24 namespace mojo { |
| 13 namespace services { | 25 namespace services { |
| 14 | 26 |
| 15 NativeViewportImpl::NativeViewportImpl(shell::Context* context, | 27 class NativeViewportService : public ::shell::ShellClientStub { |
| 16 ScopedMessagePipeHandle pipe) | 28 public: |
| 17 : context_(context), | 29 NativeViewportService(ScopedMessagePipeHandle shell_pipe) |
|
Ben Goodger (Google)
2013/12/10 16:35:03
indentation is wacky here
DaveMoore
2013/12/11 18:56:44
Done.
| |
| 18 widget_(gfx::kNullAcceleratedWidget), | 30 : shell_(shell_pipe.Pass()) { |
| 19 client_(pipe.Pass()) { | 31 shell_.SetPeer(this); |
| 20 client_.SetPeer(this); | |
| 21 } | |
| 22 | |
| 23 NativeViewportImpl::~NativeViewportImpl() { | |
| 24 } | |
| 25 | |
| 26 void NativeViewportImpl::Open() { | |
| 27 native_viewport_ = services::NativeViewport::Create(context_, this); | |
| 28 native_viewport_->Init(); | |
| 29 client_->OnCreated(); | |
| 30 } | |
| 31 | |
| 32 void NativeViewportImpl::Close() { | |
| 33 DCHECK(native_viewport_); | |
| 34 native_viewport_->Close(); | |
| 35 } | |
| 36 | |
| 37 void NativeViewportImpl::CreateGLES2Context( | |
| 38 ScopedMessagePipeHandle gles2_client) { | |
| 39 gles2_.reset(new GLES2Impl(gles2_client.Pass())); | |
| 40 CreateGLES2ContextIfNeeded(); | |
| 41 } | |
| 42 | |
| 43 void NativeViewportImpl::CreateGLES2ContextIfNeeded() { | |
| 44 if (widget_ == gfx::kNullAcceleratedWidget || !gles2_) | |
| 45 return; | |
| 46 gles2_->CreateContext(widget_, native_viewport_->GetSize()); | |
| 47 } | |
| 48 | |
| 49 bool NativeViewportImpl::OnEvent(ui::Event* ui_event) { | |
| 50 AllocationScope scope; | |
| 51 | |
| 52 Event::Builder event; | |
| 53 event.set_action(ui_event->type()); | |
| 54 event.set_time_stamp(ui_event->time_stamp().ToInternalValue()); | |
| 55 | |
| 56 if (ui_event->IsMouseEvent() || ui_event->IsTouchEvent()) { | |
| 57 ui::LocatedEvent* located_event = static_cast<ui::LocatedEvent*>(ui_event); | |
| 58 Point::Builder location; | |
| 59 location.set_x(located_event->location().x()); | |
| 60 location.set_y(located_event->location().y()); | |
| 61 event.set_location(location.Finish()); | |
| 62 } | 32 } |
| 63 | 33 |
| 64 if (ui_event->IsTouchEvent()) { | 34 virtual ~NativeViewportService() {} |
| 65 ui::TouchEvent* touch_event = static_cast<ui::TouchEvent*>(ui_event); | 35 |
| 66 TouchData::Builder touch_data; | 36 virtual void Connect(ScopedMessagePipeHandle client_pipe) MOJO_OVERRIDE { |
| 67 touch_data.set_pointer_id(touch_event->touch_id()); | 37 viewports_.push_back(new NativeViewportImpl(client_pipe.Pass())); |
|
darin (slow to review)
2013/12/10 06:12:36
It looks like this vector only grows?
DaveMoore
2013/12/11 18:56:44
It does. We need to have it clean up. But we need
| |
| 68 event.set_touch_data(touch_data.Finish()); | |
| 69 } | 38 } |
| 70 | 39 |
| 71 client_->OnEvent(event.Finish()); | 40 private: |
| 72 return false; | 41 class NativeViewportImpl : public NativeViewportStub, |
|
darin (slow to review)
2013/12/10 06:12:36
It feels like in a build where NV service is stati
DaveMoore
2013/12/11 18:56:44
I think it will be a ShellClient implementation, a
| |
| 73 } | 42 public NativeViewportDelegate { |
| 43 public: | |
| 44 NativeViewportImpl(ScopedMessagePipeHandle client_pipe) | |
| 45 : widget_(gfx::kNullAcceleratedWidget), | |
| 46 client_(client_pipe.Pass()) { | |
| 47 client_.SetPeer(this); | |
| 48 } | |
| 49 virtual ~NativeViewportImpl() {} | |
| 74 | 50 |
| 75 void NativeViewportImpl::OnAcceleratedWidgetAvailable( | 51 virtual void Open() MOJO_OVERRIDE { |
| 76 gfx::AcceleratedWidget widget) { | 52 native_viewport_ = services::NativeViewport::Create(this); |
| 77 widget_ = widget; | 53 native_viewport_->Init(); |
| 78 CreateGLES2ContextIfNeeded(); | 54 client_->OnCreated(); |
| 79 } | 55 } |
| 80 | 56 |
| 81 void NativeViewportImpl::OnResized(const gfx::Size& size) { | 57 virtual void Close() MOJO_OVERRIDE { |
| 82 } | 58 gles2_.reset(); |
| 59 DCHECK(native_viewport_); | |
| 60 native_viewport_->Close(); | |
| 61 } | |
| 83 | 62 |
| 84 void NativeViewportImpl::OnDestroyed() { | 63 virtual void CreateGLES2Context(ScopedMessagePipeHandle gles2_client) |
| 85 // TODO(beng): | 64 MOJO_OVERRIDE { |
| 86 // Destroying |gles2_| on the shell thread here hits thread checker asserts. | 65 gles2_.reset(new GLES2Impl(gles2_client.Pass())); |
| 87 // All code must stop touching the AcceleratedWidget at this point as it is | 66 CreateGLES2ContextIfNeeded(); |
| 88 // dead after this call stack. jamesr said we probably should make our own | 67 } |
| 89 // GLSurface and simply tell it to stop touching the AcceleratedWidget | 68 |
| 90 // via Destroy() but we have no good way of doing that right now given our | 69 void CreateGLES2ContextIfNeeded() { |
| 91 // current threading model so james' recommendation was just to wait until | 70 if (widget_ == gfx::kNullAcceleratedWidget || !gles2_) |
| 92 // after we move the gl service out of process. | 71 return; |
| 93 // gles2_.reset(); | 72 gles2_->CreateContext(widget_, native_viewport_->GetSize()); |
| 94 client_->OnDestroyed(); | 73 } |
| 95 } | 74 |
| 75 virtual bool OnEvent(ui::Event* ui_event) MOJO_OVERRIDE { | |
| 76 AllocationScope scope; | |
| 77 | |
| 78 Event::Builder event; | |
| 79 event.set_action(ui_event->type()); | |
| 80 event.set_time_stamp(ui_event->time_stamp().ToInternalValue()); | |
| 81 | |
| 82 if (ui_event->IsMouseEvent() || ui_event->IsTouchEvent()) { | |
| 83 ui::LocatedEvent* located_event = | |
| 84 static_cast<ui::LocatedEvent*>(ui_event); | |
| 85 Point::Builder location; | |
| 86 location.set_x(located_event->location().x()); | |
| 87 location.set_y(located_event->location().y()); | |
| 88 event.set_location(location.Finish()); | |
| 89 } | |
| 90 | |
| 91 if (ui_event->IsTouchEvent()) { | |
| 92 ui::TouchEvent* touch_event = static_cast<ui::TouchEvent*>(ui_event); | |
| 93 TouchData::Builder touch_data; | |
| 94 touch_data.set_pointer_id(touch_event->touch_id()); | |
| 95 event.set_touch_data(touch_data.Finish()); | |
| 96 } | |
| 97 | |
| 98 client_->OnEvent(event.Finish()); | |
| 99 return false; | |
| 100 } | |
| 101 | |
| 102 virtual void OnAcceleratedWidgetAvailable( | |
| 103 gfx::AcceleratedWidget widget) MOJO_OVERRIDE { | |
| 104 widget_ = widget; | |
| 105 CreateGLES2ContextIfNeeded(); | |
| 106 } | |
| 107 | |
| 108 virtual void OnResized(const gfx::Size& size) MOJO_OVERRIDE { | |
| 109 } | |
| 110 | |
| 111 virtual void OnDestroyed() MOJO_OVERRIDE { | |
| 112 base::MessageLoop::current()->Quit(); | |
| 113 } | |
| 114 | |
| 115 private: | |
| 116 gfx::AcceleratedWidget widget_; | |
| 117 scoped_ptr<services::NativeViewport> native_viewport_; | |
| 118 scoped_ptr<GLES2Impl> gles2_; | |
| 119 | |
| 120 RemotePtr<NativeViewportClient> client_; | |
| 121 }; | |
| 122 mojo::RemotePtr<::shell::Shell> shell_; | |
| 123 ScopedVector<NativeViewportImpl> viewports_; | |
| 124 }; | |
| 96 | 125 |
| 97 } // namespace services | 126 } // namespace services |
| 98 } // namespace mojo | 127 } // namespace mojo |
| 128 | |
| 129 extern "C" NATIVE_VIEWPORT_EXPORT MojoResult CDECL MojoMain( | |
|
darin (slow to review)
2013/12/10 06:12:36
I'm confused about seeing a MojoMain for the NV se
Ben Goodger (Google)
2013/12/10 16:35:03
Also what's the plan here for Android?
DaveMoore
2013/12/11 18:56:44
I think once we add support for statically linked
DaveMoore
2013/12/11 18:56:44
We're going to create this with a messageloop and
| |
| 130 const MojoHandle shell_handle) { | |
| 131 mojo::common::BindingsSupportImpl bindings_support_impl; | |
| 132 mojo::BindingsSupport::Set(&bindings_support_impl); | |
| 133 | |
| 134 mojo::ScopedMessagePipeHandle shell_pipe; | |
| 135 shell_pipe.reset(mojo::MessagePipeHandle(shell_handle)); | |
| 136 | |
| 137 base::MessageLoop loop(base::MessageLoop::TYPE_UI); | |
| 138 mojo::services::NativeViewportService app( | |
| 139 mojo::MakeScopedHandle(mojo::MessagePipeHandle(shell_handle)).Pass()); | |
| 140 base::MessageLoop::current()->Run(); | |
| 141 | |
| 142 mojo::BindingsSupport::Set(NULL); | |
| 143 return MOJO_RESULT_OK; | |
| 144 } | |
| OLD | NEW |