Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / mojo / services / native_viewport / native_viewport_service.cc
index 3d42382..8b6a34b 100644 (file)
@@ -6,10 +6,12 @@
 
 #include "base/message_loop/message_loop.h"
 #include "base/time/time.h"
-#include "mojo/services/gles2/gles2_impl.h"
+#include "mojo/public/bindings/allocation_scope.h"
+#include "mojo/services/gles2/command_buffer_impl.h"
 #include "mojo/services/native_viewport/geometry_conversions.h"
 #include "mojo/services/native_viewport/native_viewport.h"
 #include "mojom/native_viewport.h"
+#include "mojom/shell.h"
 #include "ui/events/event.h"
 
 namespace mojo {
@@ -24,34 +26,34 @@ bool IsRateLimitedEventType(ui::Event* event) {
 
 }
 
-class NativeViewportService::NativeViewportImpl
-    : public mojo::NativeViewport,
+class NativeViewportImpl
+    : public Service<mojo::NativeViewport, NativeViewportImpl, shell::Context>,
       public NativeViewportDelegate {
  public:
-  NativeViewportImpl(NativeViewportService* service,
-                     ScopedMessagePipeHandle client_handle)
-      : service_(service),
-        widget_(gfx::kNullAcceleratedWidget),
+  NativeViewportImpl()
+      : widget_(gfx::kNullAcceleratedWidget),
         waiting_for_event_ack_(false),
-        pending_event_timestamp_(0),
-        created_context_(false),
-        client_(client_handle.Pass(), this) {
-  }
+        pending_event_timestamp_(0) {}
   virtual ~NativeViewportImpl() {}
 
   virtual void Create(const Rect& bounds) MOJO_OVERRIDE {
     native_viewport_ =
-        services::NativeViewport::Create(service_->context_, this);
+        services::NativeViewport::Create(context(), this);
     native_viewport_->Init(bounds);
-    client_->OnCreated();
+    client()->OnCreated();
+    OnBoundsChanged(bounds);
   }
 
   virtual void Show() MOJO_OVERRIDE {
     native_viewport_->Show();
   }
 
+  virtual void Hide() MOJO_OVERRIDE {
+    native_viewport_->Hide();
+  }
+
   virtual void Close() MOJO_OVERRIDE {
-    gles2_.reset();
+    command_buffer_.reset();
     DCHECK(native_viewport_);
     native_viewport_->Close();
   }
@@ -64,8 +66,19 @@ class NativeViewportService::NativeViewportImpl
 
   virtual void CreateGLES2Context(ScopedMessagePipeHandle client_handle)
       MOJO_OVERRIDE {
-    gles2_.reset(new GLES2Impl(client_handle.Pass()));
-    CreateGLES2ContextIfNeeded();
+    if (command_buffer_ || command_buffer_handle_.is_valid()) {
+      LOG(ERROR) << "Can't create multiple contexts on a NativeViewport";
+      return;
+    }
+
+    // TODO(darin):
+    // CreateGLES2Context should accept a ScopedCommandBufferClientHandle once
+    // it is possible to import interface definitions from another module.  For
+    // now, we just kludge it.
+    command_buffer_handle_.reset(
+        InterfaceHandle<CommandBufferClient>(client_handle.release().value()));
+
+    CreateCommandBufferIfNeeded();
   }
 
   virtual void AckEvent(const Event& event) MOJO_OVERRIDE {
@@ -73,16 +86,17 @@ class NativeViewportService::NativeViewportImpl
     waiting_for_event_ack_ = false;
   }
 
-  void CreateGLES2ContextIfNeeded() {
-    if (created_context_)
+  void CreateCommandBufferIfNeeded() {
+    if (!command_buffer_handle_.is_valid())
       return;
-    if (widget_ == gfx::kNullAcceleratedWidget || !gles2_)
+    DCHECK(!command_buffer_.get());
+    if (widget_ == gfx::kNullAcceleratedWidget)
       return;
     gfx::Size size = native_viewport_->GetSize();
-    if (size.width() == 0 || size.height() == 0)
+    if (size.IsEmpty())
       return;
-    gles2_->CreateContext(widget_, size);
-    created_context_ = true;
+    command_buffer_.reset(new CommandBufferImpl(
+        command_buffer_handle_.Pass(), widget_, native_viewport_->GetSize()));
   }
 
   virtual bool OnEvent(ui::Event* ui_event) MOJO_OVERRIDE {
@@ -133,7 +147,7 @@ class NativeViewportService::NativeViewportImpl
       event.set_key_data(key_data.Finish());
     }
 
-    client_->OnEvent(event.Finish());
+    client()->OnEvent(event.Finish());
     waiting_for_event_ack_ = true;
     return false;
   }
@@ -141,64 +155,45 @@ class NativeViewportService::NativeViewportImpl
   virtual void OnAcceleratedWidgetAvailable(
       gfx::AcceleratedWidget widget) MOJO_OVERRIDE {
     widget_ = widget;
-    CreateGLES2ContextIfNeeded();
+    CreateCommandBufferIfNeeded();
   }
 
   virtual void OnBoundsChanged(const gfx::Rect& bounds) MOJO_OVERRIDE {
-    CreateGLES2ContextIfNeeded();
-    client_->OnBoundsChanged(bounds);
+    CreateCommandBufferIfNeeded();
+    AllocationScope scope;
+    client()->OnBoundsChanged(bounds);
   }
 
   virtual void OnDestroyed() MOJO_OVERRIDE {
-    // TODO(beng):
-    // Destroying |gles2_| on the shell thread here hits thread checker
-    // asserts. All code must stop touching the AcceleratedWidget at this
-    // point as it is dead after this call stack. jamesr said we probably
-    // should make our own GLSurface and simply tell it to stop touching the
-    // AcceleratedWidget via Destroy() but we have no good way of doing that
-    // right now given our current threading model so james' recommendation
-    // was just to wait until after we move the gl service out of process.
-    // gles2_.reset();
-    client_->OnDestroyed();
+    command_buffer_.reset();
+    client()->OnDestroyed();
     base::MessageLoop::current()->Quit();
   }
 
  private:
-  NativeViewportService* service_;
   gfx::AcceleratedWidget widget_;
   scoped_ptr<services::NativeViewport> native_viewport_;
-  scoped_ptr<GLES2Impl> gles2_;
+  ScopedCommandBufferClientHandle command_buffer_handle_;
+  scoped_ptr<CommandBufferImpl> command_buffer_;
   bool waiting_for_event_ack_;
   int64 pending_event_timestamp_;
-  bool created_context_;
-
-  RemotePtr<NativeViewportClient> client_;
 };
 
-NativeViewportService::NativeViewportService(
-    ScopedMessagePipeHandle shell_handle)
-    : shell_(shell_handle.Pass(), this),
-      context_(NULL) {
-}
-
-NativeViewportService::~NativeViewportService() {}
-
-void NativeViewportService::AcceptConnection(
-    ScopedMessagePipeHandle client_handle) {
-  // TODO(davemoore): We need a mechanism to determine when connectors
-  // go away, so we can remove viewports correctly.
-  viewports_.push_back(new NativeViewportImpl(this, client_handle.Pass()));
-}
-
 }  // namespace services
 }  // namespace mojo
 
+
 #if defined(OS_ANDROID)
 
 // Android will call this.
-mojo::services::NativeViewportService*
-    CreateNativeViewportService(mojo::ScopedMessagePipeHandle shell_handle) {
-  return new mojo::services::NativeViewportService(shell_handle.Pass());
+MOJO_NATIVE_VIEWPORT_EXPORT mojo::Application*
+    CreateNativeViewportService(mojo::shell::Context* context,
+                                mojo::ScopedShellHandle shell_handle) {
+  mojo::Application* app = new mojo::Application(shell_handle.Pass());
+  app->AddServiceFactory(
+    new mojo::ServiceFactory<mojo::services::NativeViewportImpl,
+                             mojo::shell::Context>(context));
+  return app;
 }
 
 #else
@@ -206,9 +201,11 @@ mojo::services::NativeViewportService*
 extern "C" MOJO_NATIVE_VIEWPORT_EXPORT MojoResult MojoMain(
     const MojoHandle shell_handle) {
   base::MessageLoopForUI loop;
-  mojo::services::NativeViewportService app(
-      mojo::MakeScopedHandle(mojo::MessagePipeHandle(shell_handle)).Pass());
-  base::MessageLoop::current()->Run();
+  mojo::Application app(shell_handle);
+  app.AddServiceFactory(
+    new mojo::ServiceFactory<mojo::services::NativeViewportImpl,
+                             mojo::shell::Context>);
+  loop.Run();
   return MOJO_RESULT_OK;
 }