#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 {
}
-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();
}
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 {
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 {
event.set_key_data(key_data.Finish());
}
- client_->OnEvent(event.Finish());
+ client()->OnEvent(event.Finish());
waiting_for_event_ack_ = true;
return false;
}
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
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;
}