summaryrefslogtreecommitdiffstats
path: root/mojo
diff options
context:
space:
mode:
authorpiman@chromium.org <piman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-01-23 04:02:49 +0000
committerpiman@chromium.org <piman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-01-23 04:02:49 +0000
commitc329ad7d7bdd43c89468f744a8fbd6b8f3a3c3ca (patch)
treedd0659a208a0beef98218dccee894c3770111682 /mojo
parent20af413cd157596fc2794e01dc8db14534e794ff (diff)
downloadchromium_src-c329ad7d7bdd43c89468f744a8fbd6b8f3a3c3ca.zip
chromium_src-c329ad7d7bdd43c89468f744a8fbd6b8f3a3c3ca.tar.gz
chromium_src-c329ad7d7bdd43c89468f744a8fbd6b8f3a3c3ca.tar.bz2
Internalize the GLES2Client logic into libmojo_gles2
Expose an API that looks a bit like EGL to create/destroy contexts/make them current etc. This allows libmojo_gles2 to properly hide the GLES2 implementation. A follow up wil replace it by a proper CommandBuffer interface, etc. Some caveats: - we need a BindingsSupport in libmojo_gles2 because it's a component. We need to integrate with the embedder's run loop because we need to asynchronously wait on handles, so we pass in the embedder's BindingsSupport. We should probably pass an abstraction over the embedder's run loop, and have an implementation of BindingsSupport on top of that (note, currently on Android libmojo_gles2 is statically linked into the client, so we can't have 2 different BindingsSupport). - creating a context is currently asynchronous, and that's awkward. - we have to expose the chrome types (GLES2Implementation/ContextSupport) for the compositor app. That's awkward too. - some things like RequestAnimationFrames don't belong there at all. - libmojo_gles2 is a C API so we can't really have type safety, and some things like callbacks are a PITA. BUG=333157 Review URL: https://codereview.chromium.org/132913004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@246516 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'mojo')
-rw-r--r--mojo/apps/js/bindings/gl/context.cc60
-rw-r--r--mojo/apps/js/bindings/gl/context.h28
-rw-r--r--mojo/apps/js/bindings/gl/module.cc12
-rw-r--r--mojo/apps/js/main.cc7
-rw-r--r--mojo/apps/js/main.js15
-rw-r--r--mojo/examples/aura_demo/aura_demo.cc5
-rw-r--r--mojo/examples/compositor_app/compositor_app.cc5
-rw-r--r--mojo/examples/compositor_app/gles2_client_impl.cc57
-rw-r--r--mojo/examples/compositor_app/gles2_client_impl.h20
-rw-r--r--mojo/examples/sample_app/gles2_client_impl.cc35
-rw-r--r--mojo/examples/sample_app/gles2_client_impl.h20
-rw-r--r--mojo/examples/sample_app/sample_app.cc5
-rw-r--r--mojo/gles2/gles2_client_impl.cc63
-rw-r--r--mojo/gles2/gles2_client_impl.h53
-rw-r--r--mojo/gles2/gles2_support_impl.cc67
-rw-r--r--mojo/gles2/gles2_support_impl.h20
-rw-r--r--mojo/mojo.gyp4
-rw-r--r--mojo/mojo_examples.gypi1
-rw-r--r--mojo/public/gles2/gles2.h25
-rw-r--r--mojo/public/gles2/gles2_cpp.h23
-rw-r--r--mojo/public/gles2/gles2_private.cc45
-rw-r--r--mojo/public/gles2/gles2_private.h18
-rw-r--r--mojo/public/gles2/gles2_types.h31
23 files changed, 512 insertions, 107 deletions
diff --git a/mojo/apps/js/bindings/gl/context.cc b/mojo/apps/js/bindings/gl/context.cc
index ade9883..878a873 100644
--- a/mojo/apps/js/bindings/gl/context.cc
+++ b/mojo/apps/js/bindings/gl/context.cc
@@ -9,6 +9,7 @@
#include "gin/arguments.h"
#include "gin/array_buffer.h"
#include "gin/object_template_builder.h"
+#include "gin/per_context_data.h"
#include "mojo/public/gles2/gles2.h"
namespace gin {
@@ -31,9 +32,12 @@ namespace gl {
gin::WrapperInfo Context::kWrapperInfo = { gin::kEmbedderNativeGin };
-gin::Handle<Context> Context::Create(v8::Isolate* isolate, uint64_t encoded,
- int width, int height) {
- return gin::CreateHandle(isolate, new Context(encoded, width, height));
+gin::Handle<Context> Context::Create(
+ v8::Isolate* isolate,
+ mojo::Handle handle,
+ v8::Handle<v8::Function> did_create_callback) {
+ return gin::CreateHandle(isolate,
+ new Context(isolate, handle, did_create_callback));
}
void Context::BufferData(GLenum target, const gin::ArrayBufferView& buffer,
@@ -144,11 +148,55 @@ gin::ObjectTemplateBuilder Context::GetObjectTemplateBuilder(
.SetMethod("viewport", glViewport);
}
-Context::Context(uint64_t encoded, int width, int height)
- : encoded_(encoded) {
+Context::Context(v8::Isolate* isolate,
+ mojo::Handle handle,
+ v8::Handle<v8::Function> did_create_callback) {
+ v8::Handle<v8::Context> context = isolate->GetCurrentContext();
+ runner_ = gin::PerContextData::From(context)->runner()->GetWeakPtr();
+ did_create_callback_.Reset(isolate, did_create_callback);
+ context_ = MojoGLES2CreateContext(
+ handle.value(),
+ &DidCreateContextThunk,
+ &ContextLostThunk,
+ NULL,
+ this);
+}
+
+Context::~Context() {
+ MojoGLES2DestroyContext(context_);
+}
+
+void Context::DidCreateContext(uint32_t width, uint32_t height) {
// TODO(aa): When we want to support multiple contexts, we should add
// Context::MakeCurrent() for developers to switch between them.
- MojoGLES2MakeCurrent(encoded_);
+ MojoGLES2MakeCurrent(context_);
+ if (!runner_)
+ return;
+ gin::Runner::Scope scope(runner_.get());
+ v8::Isolate* isolate = runner_->isolate();
+
+ v8::Handle<v8::Function> callback = v8::Local<v8::Function>::New(
+ isolate, did_create_callback_);
+
+ v8::Handle<v8::Value> args[] = {
+ gin::ConvertToV8(isolate, width),
+ gin::ConvertToV8(isolate, height),
+ };
+ runner_->Call(callback, runner_->global(), 2, args);
+}
+
+void Context::DidCreateContextThunk(
+ void* closure,
+ uint32_t width,
+ uint32_t height) {
+ static_cast<Context*>(closure)->DidCreateContext(width, height);
+}
+
+void Context::ContextLost() {
+}
+
+void Context::ContextLostThunk(void* closure) {
+ static_cast<Context*>(closure)->ContextLost();
}
} // namespace gl
diff --git a/mojo/apps/js/bindings/gl/context.h b/mojo/apps/js/bindings/gl/context.h
index 081dbb2..de47f15 100644
--- a/mojo/apps/js/bindings/gl/context.h
+++ b/mojo/apps/js/bindings/gl/context.h
@@ -7,9 +7,13 @@
#include <GLES2/gl2.h>
+#include "base/memory/weak_ptr.h"
#include "gin/handle.h"
#include "gin/public/wrapper_info.h"
+#include "gin/runner.h"
#include "gin/wrappable.h"
+#include "mojo/apps/js/bindings/handle.h"
+#include "mojo/public/gles2/gles2.h"
#include "v8/include/v8.h"
namespace gin {
@@ -26,8 +30,11 @@ class Context : public gin::Wrappable<Context> {
public:
static gin::WrapperInfo kWrapperInfo;
- static gin::Handle<Context> Create(v8::Isolate* isolate, uint64_t encoded,
- int width, int height);
+ // TODO(piman): lost context callback, draw animation frame callback.
+ static gin::Handle<Context> Create(
+ v8::Isolate* isolate,
+ mojo::Handle handle,
+ v8::Handle<v8::Function> did_create_callback);
static void BufferData(GLenum target, const gin::ArrayBufferView& buffer,
GLenum usage);
@@ -50,9 +57,22 @@ class Context : public gin::Wrappable<Context> {
virtual gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
v8::Isolate* isolate) OVERRIDE;
- Context(uint64_t encoded, int width, int height);
+ explicit Context(v8::Isolate* isolate,
+ mojo::Handle handle,
+ v8::Handle<v8::Function> did_create_callback);
+ virtual ~Context();
- uint64_t encoded_;
+ void DidCreateContext(uint32_t width, uint32_t height);
+ static void DidCreateContextThunk(
+ void* closure,
+ uint32_t width,
+ uint32_t height);
+ void ContextLost();
+ static void ContextLostThunk(void* closure);
+
+ base::WeakPtr<gin::Runner> runner_;
+ v8::Persistent<v8::Function> did_create_callback_;
+ MojoGLES2Context context_;
};
} // namespace gl
diff --git a/mojo/apps/js/bindings/gl/module.cc b/mojo/apps/js/bindings/gl/module.cc
index 2c67ac1..973e9be 100644
--- a/mojo/apps/js/bindings/gl/module.cc
+++ b/mojo/apps/js/bindings/gl/module.cc
@@ -4,15 +4,13 @@
#include "mojo/apps/js/bindings/gl/module.h"
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-
#include "base/logging.h"
#include "gin/arguments.h"
#include "gin/object_template_builder.h"
#include "gin/per_isolate_data.h"
#include "gin/wrappable.h"
#include "mojo/apps/js/bindings/gl/context.h"
+#include "mojo/apps/js/bindings/handle.h"
namespace mojo {
namespace js {
@@ -24,9 +22,11 @@ namespace {
gin::WrapperInfo kWrapperInfo = { gin::kEmbedderNativeGin };
-gin::Handle<Context> CreateContext(const gin::Arguments& args, uint64_t encoded,
- int width, int height) {
- return Context::Create(args.isolate(), encoded, width, height);
+gin::Handle<Context> CreateContext(
+ const gin::Arguments& args,
+ mojo::Handle handle,
+ v8::Handle<v8::Function> did_create_callback) {
+ return Context::Create(args.isolate(), handle, did_create_callback);
}
} // namespace
diff --git a/mojo/apps/js/main.cc b/mojo/apps/js/main.cc
index bfc6e2c..50f46d4 100644
--- a/mojo/apps/js/main.cc
+++ b/mojo/apps/js/main.cc
@@ -5,7 +5,7 @@
#include "base/message_loop/message_loop.h"
#include "gin/public/isolate_holder.h"
#include "mojo/apps/js/mojo_runner_delegate.h"
-#include "mojo/public/gles2/gles2.h"
+#include "mojo/public/gles2/gles2_cpp.h"
#include "mojo/public/system/core_cpp.h"
#include "mojo/public/system/macros.h"
@@ -37,10 +37,7 @@ void Start(MojoHandle pipe, const std::string& module) {
} // namespace mojo
extern "C" MOJO_APPS_JS_EXPORT MojoResult CDECL MojoMain(MojoHandle pipe) {
- MojoGLES2Initialize();
-
+ mojo::GLES2Initializer gles2;
mojo::apps::Start(pipe, "mojo/apps/js/main");
-
- MojoGLES2Terminate();
return MOJO_RESULT_OK;
}
diff --git a/mojo/apps/js/main.js b/mojo/apps/js/main.js
index 4f821a7..9ca9e9d 100644
--- a/mojo/apps/js/main.js
+++ b/mojo/apps/js/main.js
@@ -11,7 +11,6 @@ define([
'mojo/apps/js/bindings/gl',
'mojo/apps/js/bindings/threading',
'mojom/native_viewport',
- 'mojom/gles2',
'mojom/shell',
], function(console,
monotonicClock,
@@ -21,7 +20,6 @@ define([
gljs,
threading,
nativeViewport,
- gles2,
shell) {
const VERTEX_SHADER_SOURCE = [
@@ -297,7 +295,7 @@ define([
this.remote_ = remote;
var pipe = core.createMessagePipe();
- new connector.Connection(pipe.handle0, GLES2ClientImpl, gles2.GLES2Proxy);
+ new GLES2ClientImpl(pipe.handle0);
this.remote_.open();
this.remote_.createGLES2Context(pipe.handle1);
@@ -313,20 +311,15 @@ define([
};
- function GLES2ClientImpl(remote) {
- this.remote_ = remote;
+ function GLES2ClientImpl(remotePipe) {
+ this.gl_ = new gljs.Context(remotePipe, this.didCreateContext.bind(this));
this.lastTime_ = monotonicClock.seconds();
this.angle_ = 45;
}
- GLES2ClientImpl.prototype =
- Object.create(gles2.GLES2ClientStub.prototype);
- GLES2ClientImpl.prototype.didCreateContext = function(encoded,
- width,
- height) {
+ GLES2ClientImpl.prototype.didCreateContext = function(width, height) {
this.width_ = width;
this.height_ = height;
- this.gl_ = new gljs.Context(encoded, width, height);
this.program_ = loadProgram(this.gl_);
this.positionLocation_ =
this.gl_.getAttribLocation(this.program_, 'a_position');
diff --git a/mojo/examples/aura_demo/aura_demo.cc b/mojo/examples/aura_demo/aura_demo.cc
index 64fe621..4b13103 100644
--- a/mojo/examples/aura_demo/aura_demo.cc
+++ b/mojo/examples/aura_demo/aura_demo.cc
@@ -13,7 +13,7 @@
#include "mojo/examples/compositor_app/compositor_host.h"
#include "mojo/examples/compositor_app/gles2_client_impl.h"
#include "mojo/public/bindings/lib/remote_ptr.h"
-#include "mojo/public/gles2/gles2.h"
+#include "mojo/public/gles2/gles2_cpp.h"
#include "mojo/public/system/core.h"
#include "mojo/public/system/macros.h"
#include "mojom/native_viewport.h"
@@ -195,7 +195,7 @@ extern "C" AURA_DEMO_EXPORT MojoResult CDECL MojoMain(
CommandLine::Init(0, NULL);
base::AtExitManager at_exit;
base::MessageLoop loop;
- MojoGLES2Initialize();
+ mojo::GLES2Initializer gles2;
// TODO(beng): This crashes in a DCHECK on X11 because this thread's
// MessageLoop is not of TYPE_UI. I think we need a way to build
@@ -205,6 +205,5 @@ extern "C" AURA_DEMO_EXPORT MojoResult CDECL MojoMain(
mojo::MakeScopedHandle(mojo::MessagePipeHandle(shell_handle)).Pass());
loop.Run();
- MojoGLES2Terminate();
return MOJO_RESULT_OK;
}
diff --git a/mojo/examples/compositor_app/compositor_app.cc b/mojo/examples/compositor_app/compositor_app.cc
index d2547fd..a4e1182 100644
--- a/mojo/examples/compositor_app/compositor_app.cc
+++ b/mojo/examples/compositor_app/compositor_app.cc
@@ -9,7 +9,7 @@
#include "mojo/examples/compositor_app/compositor_host.h"
#include "mojo/examples/compositor_app/gles2_client_impl.h"
#include "mojo/public/bindings/lib/remote_ptr.h"
-#include "mojo/public/gles2/gles2.h"
+#include "mojo/public/gles2/gles2_cpp.h"
#include "mojo/public/system/core.h"
#include "mojo/public/system/macros.h"
#include "mojom/native_viewport.h"
@@ -96,12 +96,11 @@ class SampleApp : public ShellClient {
extern "C" SAMPLE_APP_EXPORT MojoResult CDECL MojoMain(
MojoHandle shell_handle) {
base::MessageLoop loop;
- MojoGLES2Initialize();
+ mojo::GLES2Initializer gles2;
mojo::examples::SampleApp app(
mojo::MakeScopedHandle(mojo::MessagePipeHandle(shell_handle)).Pass());
loop.Run();
- MojoGLES2Terminate();
return MOJO_RESULT_OK;
}
diff --git a/mojo/examples/compositor_app/gles2_client_impl.cc b/mojo/examples/compositor_app/gles2_client_impl.cc
index 7bd0b06..3b59f96 100644
--- a/mojo/examples/compositor_app/gles2_client_impl.cc
+++ b/mojo/examples/compositor_app/gles2_client_impl.cc
@@ -5,8 +5,8 @@
#include "mojo/examples/compositor_app/gles2_client_impl.h"
#include "base/debug/trace_event.h"
-#include "gpu/command_buffer/client/gles2_implementation.h"
-#include "mojo/public/gles2/gles2.h"
+#include "gpu/command_buffer/client/context_support.h"
+#include "gpu/command_buffer/client/gles2_interface.h"
namespace mojo {
namespace examples {
@@ -14,33 +14,58 @@ namespace examples {
GLES2ClientImpl::GLES2ClientImpl(
ScopedMessagePipeHandle pipe,
const base::Callback<void(gfx::Size)>& context_created_callback)
- : context_created_callback_(context_created_callback),
- impl_(NULL),
- service_(pipe.Pass(), this) {
+ : context_created_callback_(context_created_callback) {
+ context_ = MojoGLES2CreateContext(
+ pipe.release().value(),
+ &DidCreateContextThunk,
+ &ContextLostThunk,
+ NULL,
+ this);
}
-GLES2ClientImpl::~GLES2ClientImpl() { service_->Destroy(); }
+GLES2ClientImpl::~GLES2ClientImpl() {
+ if (context_)
+ MojoGLES2DestroyContext(context_);
+}
+
+gpu::gles2::GLES2Interface* GLES2ClientImpl::Interface() const {
+ if (!context_)
+ return NULL;
+ return static_cast<gpu::gles2::GLES2Interface*>(
+ MojoGLES2GetGLES2Interface(context_));
+}
-void GLES2ClientImpl::DidCreateContext(uint64_t encoded,
- uint32_t width,
+gpu::ContextSupport* GLES2ClientImpl::Support() const {
+ if (!context_)
+ return NULL;
+ return static_cast<gpu::ContextSupport*>(
+ MojoGLES2GetContextSupport(context_));
+}
+
+void GLES2ClientImpl::DidCreateContext(uint32_t width,
uint32_t height) {
TRACE_EVENT0("compositor_app", "DidCreateContext");
- impl_ = reinterpret_cast<gpu::gles2::GLES2Implementation*>(encoded);
if (!context_created_callback_.is_null())
context_created_callback_.Run(gfx::Size(width, height));
}
-gpu::gles2::GLES2Interface* GLES2ClientImpl::Interface() const {
- return impl_;
+void GLES2ClientImpl::DidCreateContextThunk(
+ void* closure,
+ uint32_t width,
+ uint32_t height) {
+ static_cast<GLES2ClientImpl*>(closure)->DidCreateContext(width, height);
}
-gpu::ContextSupport* GLES2ClientImpl::Support() const {
- return impl_;
+void GLES2ClientImpl::ContextLost() {
+ if (context_) {
+ MojoGLES2DestroyContext(context_);
+ context_ = NULL;
+ }
}
-void GLES2ClientImpl::ContextLost() { impl_ = NULL; }
-
-void GLES2ClientImpl::DrawAnimationFrame() {}
+void GLES2ClientImpl::ContextLostThunk(void* closure) {
+ static_cast<GLES2ClientImpl*>(closure)->ContextLost();
+}
} // namespace examples
} // namespace mojo
diff --git a/mojo/examples/compositor_app/gles2_client_impl.h b/mojo/examples/compositor_app/gles2_client_impl.h
index fbb49b0..3c91cef 100644
--- a/mojo/examples/compositor_app/gles2_client_impl.h
+++ b/mojo/examples/compositor_app/gles2_client_impl.h
@@ -8,7 +8,7 @@
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "mojo/public/bindings/lib/remote_ptr.h"
-#include "mojom/gles2.h"
+#include "mojo/public/gles2/gles2.h"
#include "mojom/native_viewport.h"
#include "ui/gfx/size.h"
@@ -16,14 +16,13 @@ namespace gpu {
class ContextSupport;
namespace gles2 {
class GLES2Interface;
-class GLES2Implementation;
}
}
namespace mojo {
namespace examples {
-class GLES2ClientImpl : public GLES2Client {
+class GLES2ClientImpl {
public:
GLES2ClientImpl(
ScopedMessagePipeHandle pipe,
@@ -34,16 +33,17 @@ class GLES2ClientImpl : public GLES2Client {
gpu::ContextSupport* Support() const;
private:
- virtual void DidCreateContext(uint64_t encoded,
- uint32_t width,
- uint32_t height) MOJO_OVERRIDE;
- virtual void ContextLost() MOJO_OVERRIDE;
- virtual void DrawAnimationFrame() MOJO_OVERRIDE;
+ void DidCreateContext(uint32_t width, uint32_t height);
+ static void DidCreateContextThunk(
+ void* closure,
+ uint32_t width,
+ uint32_t height);
+ void ContextLost();
+ static void ContextLostThunk(void* closure);
base::Callback<void(gfx::Size viewport_size)> context_created_callback_;
- gpu::gles2::GLES2Implementation* impl_;
- RemotePtr<GLES2> service_;
+ MojoGLES2Context context_;
MOJO_DISALLOW_COPY_AND_ASSIGN(GLES2ClientImpl);
};
diff --git a/mojo/examples/sample_app/gles2_client_impl.cc b/mojo/examples/sample_app/gles2_client_impl.cc
index 644645c..b3f2003 100644
--- a/mojo/examples/sample_app/gles2_client_impl.cc
+++ b/mojo/examples/sample_app/gles2_client_impl.cc
@@ -22,12 +22,17 @@ float CalculateDragDistance(const gfx::PointF& start, const Point& end) {
}
GLES2ClientImpl::GLES2ClientImpl(ScopedMessagePipeHandle pipe)
- : getting_animation_frames_(false),
- service_(pipe.Pass(), this) {
+ : getting_animation_frames_(false) {
+ context_ = MojoGLES2CreateContext(
+ pipe.release().value(),
+ &DidCreateContextThunk,
+ &ContextLostThunk,
+ &DrawAnimationFrameThunk,
+ this);
}
GLES2ClientImpl::~GLES2ClientImpl() {
- service_->Destroy();
+ MojoGLES2DestroyContext(context_);
}
void GLES2ClientImpl::HandleInputEvent(const Event& event) {
@@ -70,19 +75,29 @@ void GLES2ClientImpl::HandleInputEvent(const Event& event) {
}
}
-void GLES2ClientImpl::DidCreateContext(uint64_t encoded,
- uint32_t width,
+void GLES2ClientImpl::DidCreateContext(uint32_t width,
uint32_t height) {
- MojoGLES2MakeCurrent(encoded);
+ MojoGLES2MakeCurrent(context_);
cube_.Init(width, height);
RequestAnimationFrames();
}
+void GLES2ClientImpl::DidCreateContextThunk(
+ void* closure,
+ uint32_t width,
+ uint32_t height) {
+ static_cast<GLES2ClientImpl*>(closure)->DidCreateContext(width, height);
+}
+
void GLES2ClientImpl::ContextLost() {
CancelAnimationFrames();
}
+void GLES2ClientImpl::ContextLostThunk(void* closure) {
+ static_cast<GLES2ClientImpl*>(closure)->ContextLost();
+}
+
void GLES2ClientImpl::DrawAnimationFrame() {
MojoTimeTicks now = GetTimeTicksNow();
MojoTimeTicks offset = now - last_time_;
@@ -94,15 +109,19 @@ void GLES2ClientImpl::DrawAnimationFrame() {
MojoGLES2SwapBuffers();
}
+void GLES2ClientImpl::DrawAnimationFrameThunk(void* closure) {
+ static_cast<GLES2ClientImpl*>(closure)->DrawAnimationFrame();
+}
+
void GLES2ClientImpl::RequestAnimationFrames() {
getting_animation_frames_ = true;
- service_->RequestAnimationFrames();
+ MojoGLES2RequestAnimationFrames(context_);
last_time_ = GetTimeTicksNow();
}
void GLES2ClientImpl::CancelAnimationFrames() {
getting_animation_frames_ = false;
- service_->CancelAnimationFrames();
+ MojoGLES2CancelAnimationFrames(context_);
}
} // namespace examples
diff --git a/mojo/examples/sample_app/gles2_client_impl.h b/mojo/examples/sample_app/gles2_client_impl.h
index 35f59ff..d927c24 100644
--- a/mojo/examples/sample_app/gles2_client_impl.h
+++ b/mojo/examples/sample_app/gles2_client_impl.h
@@ -7,14 +7,14 @@
#include "mojo/examples/sample_app/spinning_cube.h"
#include "mojo/public/bindings/lib/remote_ptr.h"
-#include "mojom/gles2.h"
+#include "mojo/public/gles2/gles2.h"
#include "mojom/native_viewport.h"
#include "ui/gfx/point_f.h"
namespace mojo {
namespace examples {
-class GLES2ClientImpl : public GLES2Client {
+class GLES2ClientImpl {
public:
explicit GLES2ClientImpl(ScopedMessagePipeHandle pipe);
virtual ~GLES2ClientImpl();
@@ -22,11 +22,15 @@ class GLES2ClientImpl : public GLES2Client {
void HandleInputEvent(const Event& event);
private:
- virtual void DidCreateContext(uint64_t encoded,
- uint32_t width,
- uint32_t height) MOJO_OVERRIDE;
- virtual void ContextLost() MOJO_OVERRIDE;
- virtual void DrawAnimationFrame() MOJO_OVERRIDE;
+ void DidCreateContext(uint32_t width, uint32_t height);
+ static void DidCreateContextThunk(
+ void* closure,
+ uint32_t width,
+ uint32_t height);
+ void ContextLost();
+ static void ContextLostThunk(void* closure);
+ void DrawAnimationFrame();
+ static void DrawAnimationFrameThunk(void* closure);
void RequestAnimationFrames();
void CancelAnimationFrames();
@@ -38,7 +42,7 @@ class GLES2ClientImpl : public GLES2Client {
MojoTimeTicks drag_start_time_;
bool getting_animation_frames_;
- RemotePtr<GLES2> service_;
+ MojoGLES2Context context_;
MOJO_DISALLOW_COPY_AND_ASSIGN(GLES2ClientImpl);
};
diff --git a/mojo/examples/sample_app/sample_app.cc b/mojo/examples/sample_app/sample_app.cc
index 8b3d763..810ea27 100644
--- a/mojo/examples/sample_app/sample_app.cc
+++ b/mojo/examples/sample_app/sample_app.cc
@@ -8,7 +8,7 @@
#include "mojo/examples/sample_app/gles2_client_impl.h"
#include "mojo/public/bindings/lib/remote_ptr.h"
#include "mojo/public/environment/environment.h"
-#include "mojo/public/gles2/gles2.h"
+#include "mojo/public/gles2/gles2_cpp.h"
#include "mojo/public/system/core.h"
#include "mojo/public/system/macros.h"
#include "mojo/public/utility/run_loop.h"
@@ -86,12 +86,11 @@ extern "C" SAMPLE_APP_EXPORT MojoResult CDECL MojoMain(
MojoHandle shell_handle) {
mojo::Environment env;
mojo::RunLoop loop;
- MojoGLES2Initialize();
+ mojo::GLES2Initializer gles2;
mojo::examples::SampleApp app(
mojo::MakeScopedHandle(mojo::MessagePipeHandle(shell_handle)).Pass());
loop.Run();
- MojoGLES2Terminate();
return MOJO_RESULT_OK;
}
diff --git a/mojo/gles2/gles2_client_impl.cc b/mojo/gles2/gles2_client_impl.cc
new file mode 100644
index 0000000..6f4e21b
--- /dev/null
+++ b/mojo/gles2/gles2_client_impl.cc
@@ -0,0 +1,63 @@
+// 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/gles2/gles2_client_impl.h"
+
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+#include "mojo/public/gles2/gles2.h"
+
+namespace mojo {
+namespace gles2 {
+
+GLES2ClientImpl::GLES2ClientImpl(MojoAsyncWaiter* async_waiter,
+ ScopedMessagePipeHandle pipe,
+ MojoGLES2ContextCreated created_callback,
+ MojoGLES2ContextLost lost_callback,
+ MojoGLES2DrawAnimationFrame animation_callback,
+ void* closure)
+ : service_(pipe.Pass(), this, async_waiter),
+ implementation_(NULL),
+ created_callback_(created_callback),
+ lost_callback_(lost_callback),
+ animation_callback_(animation_callback),
+ closure_(closure) {
+}
+
+GLES2ClientImpl::~GLES2ClientImpl() {
+ service_->Destroy();
+}
+
+void GLES2ClientImpl::RequestAnimationFrames() {
+ service_->RequestAnimationFrames();
+}
+
+void GLES2ClientImpl::CancelAnimationFrames() {
+ service_->CancelAnimationFrames();
+}
+
+void GLES2ClientImpl::DidCreateContext(uint64_t encoded,
+ uint32_t width,
+ uint32_t height) {
+ // Ack, Hans! It's the giant hack.
+ // TODO(abarth): Replace this hack with something more disciplined. Most
+ // likley, we should receive a MojoHandle that we use to wire up the
+ // client side of an out-of-process command buffer. Given that we're
+ // still in-process, we just reinterpret_cast the value into a GL interface.
+ implementation_ = reinterpret_cast<gpu::gles2::GLES2Implementation*>(
+ static_cast<uintptr_t>(encoded));
+ created_callback_(closure_, width, height);
+}
+
+void GLES2ClientImpl::ContextLost() {
+ lost_callback_(closure_);
+}
+
+void GLES2ClientImpl::DrawAnimationFrame() {
+ animation_callback_(closure_);
+}
+
+} // namespace examples
+} // namespace mojo
diff --git a/mojo/gles2/gles2_client_impl.h b/mojo/gles2/gles2_client_impl.h
new file mode 100644
index 0000000..79c833c
--- /dev/null
+++ b/mojo/gles2/gles2_client_impl.h
@@ -0,0 +1,53 @@
+// 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.
+
+#ifndef MOJO_GLES2_GLES2_CLIENT_IMPL_H_
+#define MOJO_GLES2_GLES2_CLIENT_IMPL_H_
+
+#include "gpu/command_buffer/client/gles2_implementation.h"
+#include "mojo/public/bindings/lib/remote_ptr.h"
+#include "mojo/public/gles2/gles2.h"
+#include "mojom/gles2.h"
+
+struct MojoGLES2ContextPrivate {};
+
+namespace mojo {
+namespace gles2 {
+
+class GLES2ClientImpl : public GLES2Client, public MojoGLES2ContextPrivate {
+ public:
+ explicit GLES2ClientImpl(MojoAsyncWaiter* async_waiter,
+ ScopedMessagePipeHandle pipe,
+ MojoGLES2ContextCreated created_callback,
+ MojoGLES2ContextLost lost_callback,
+ MojoGLES2DrawAnimationFrame animation_callback,
+ void* closure);
+ virtual ~GLES2ClientImpl();
+ gpu::gles2::GLES2Interface* interface() const { return implementation_; }
+ gpu::ContextSupport* context_support() const { return implementation_; }
+ void RequestAnimationFrames();
+ void CancelAnimationFrames();
+
+ private:
+ virtual void DidCreateContext(uint64_t encoded,
+ uint32_t width,
+ uint32_t height) MOJO_OVERRIDE;
+ virtual void ContextLost() MOJO_OVERRIDE;
+ virtual void DrawAnimationFrame() MOJO_OVERRIDE;
+
+
+ RemotePtr<GLES2> service_;
+ gpu::gles2::GLES2Implementation* implementation_;
+ MojoGLES2ContextCreated created_callback_;
+ MojoGLES2ContextLost lost_callback_;
+ MojoGLES2DrawAnimationFrame animation_callback_;
+ void* closure_;
+
+ MOJO_DISALLOW_COPY_AND_ASSIGN(GLES2ClientImpl);
+};
+
+} // namespace gles2
+} // namespace mojo
+
+#endif // MOJO_GLES2_GLES2_CLIENT_IMPL_H_
diff --git a/mojo/gles2/gles2_support_impl.cc b/mojo/gles2/gles2_support_impl.cc
index f8b96f6..4cd3b59 100644
--- a/mojo/gles2/gles2_support_impl.cc
+++ b/mojo/gles2/gles2_support_impl.cc
@@ -6,6 +6,7 @@
#include "base/lazy_instance.h"
#include "gpu/command_buffer/client/gles2_interface.h"
+#include "mojo/gles2/gles2_client_impl.h"
#include "mojo/public/gles2/gles2_interface.h"
#include "mojo/public/gles2/gles2_private.h"
@@ -40,31 +41,73 @@ base::LazyInstance<GLES2ImplForCommandBuffer> g_gles2_interface =
} // anonymous namespace
+GLES2SupportImpl::GLES2SupportImpl() : async_waiter_(NULL) {}
GLES2SupportImpl::~GLES2SupportImpl() {}
// static
void GLES2SupportImpl::Init() { GLES2Support::Init(new GLES2SupportImpl()); }
-void GLES2SupportImpl::Initialize() {}
+void GLES2SupportImpl::Initialize(MojoAsyncWaiter* async_waiter) {
+ DCHECK(!async_waiter_);
+ DCHECK(async_waiter);
+ async_waiter_ = async_waiter;
+}
+
+void GLES2SupportImpl::Terminate() {
+ DCHECK(!async_waiter_);
+ async_waiter_ = NULL;
+}
+
+MojoGLES2Context GLES2SupportImpl::CreateContext(
+ MessagePipeHandle handle,
+ MojoGLES2ContextCreated created_callback,
+ MojoGLES2ContextLost lost_callback,
+ MojoGLES2DrawAnimationFrame animation_callback,
+ void* closure) {
+ mojo::ScopedMessagePipeHandle scoped_handle =
+ mojo::ScopedMessagePipeHandle(mojo::MessagePipeHandle(handle));
+ return new GLES2ClientImpl(async_waiter_,
+ scoped_handle.Pass(),
+ created_callback,
+ lost_callback,
+ animation_callback,
+ closure);
+}
-void GLES2SupportImpl::Terminate() {}
+void GLES2SupportImpl::DestroyContext(MojoGLES2Context context) {
+ delete static_cast<GLES2ClientImpl*>(context);
+}
-void GLES2SupportImpl::MakeCurrent(uint64_t encoded) {
- // Ack, Hans! It's the giant hack.
- // TODO(abarth): Replace this hack with something more disciplined. Most
- // likley, we should receive a MojoHandle that we use to wire up the
- // client side of an out-of-process command buffer. Given that we're
- // still in-process, we just reinterpret_cast the value into a GL interface.
- gpu::gles2::GLES2Interface* gl_interface =
- reinterpret_cast<gpu::gles2::GLES2Interface*>(
- static_cast<uintptr_t>(encoded));
- g_gles2_interface.Get().set_gpu_interface(gl_interface);
+void GLES2SupportImpl::MakeCurrent(MojoGLES2Context context) {
+ gpu::gles2::GLES2Interface* interface = NULL;
+ if (context) {
+ GLES2ClientImpl* client = static_cast<GLES2ClientImpl*>(context);
+ interface = client->interface();
+ DCHECK(interface);
+ }
+ g_gles2_interface.Get().set_gpu_interface(interface);
}
void GLES2SupportImpl::SwapBuffers() {
g_gles2_interface.Get().gpu_interface()->SwapBuffers();
}
+void GLES2SupportImpl::RequestAnimationFrames(MojoGLES2Context context) {
+ static_cast<GLES2ClientImpl*>(context)->RequestAnimationFrames();
+}
+
+void GLES2SupportImpl::CancelAnimationFrames(MojoGLES2Context context) {
+ static_cast<GLES2ClientImpl*>(context)->CancelAnimationFrames();
+}
+
+void* GLES2SupportImpl::GetGLES2Interface(MojoGLES2Context context) {
+ return static_cast<GLES2ClientImpl*>(context)->interface();
+}
+
+void* GLES2SupportImpl::GetContextSupport(MojoGLES2Context context) {
+ return static_cast<GLES2ClientImpl*>(context)->context_support();
+}
+
GLES2Interface* GLES2SupportImpl::GetGLES2InterfaceForCurrentContext() {
return &g_gles2_interface.Get();
}
diff --git a/mojo/gles2/gles2_support_impl.h b/mojo/gles2/gles2_support_impl.h
index abe6adc..90d1ea3 100644
--- a/mojo/gles2/gles2_support_impl.h
+++ b/mojo/gles2/gles2_support_impl.h
@@ -18,11 +18,27 @@ class MOJO_GLES2_IMPL_EXPORT GLES2SupportImpl : public GLES2Support {
static void Init();
- virtual void Initialize() OVERRIDE;
+ virtual void Initialize(MojoAsyncWaiter* async_waiter) OVERRIDE;
virtual void Terminate() OVERRIDE;
- virtual void MakeCurrent(uint64_t encoded) OVERRIDE;
+ virtual MojoGLES2Context CreateContext(
+ MessagePipeHandle handle,
+ MojoGLES2ContextCreated created_callback,
+ MojoGLES2ContextLost lost_callback,
+ MojoGLES2DrawAnimationFrame animation_callback,
+ void* closure) OVERRIDE;
+ virtual void DestroyContext(MojoGLES2Context context) OVERRIDE;
+ virtual void MakeCurrent(MojoGLES2Context context) OVERRIDE;
virtual void SwapBuffers() OVERRIDE;
+ virtual void RequestAnimationFrames(MojoGLES2Context context) OVERRIDE;
+ virtual void CancelAnimationFrames(MojoGLES2Context context) OVERRIDE;
+ virtual void* GetGLES2Interface(MojoGLES2Context context) OVERRIDE;
+ virtual void* GetContextSupport(MojoGLES2Context context) OVERRIDE;
virtual GLES2Interface* GetGLES2InterfaceForCurrentContext() OVERRIDE;
+
+ private:
+ GLES2SupportImpl();
+
+ MojoAsyncWaiter* async_waiter_;
};
} // namespace gles2
diff --git a/mojo/mojo.gyp b/mojo/mojo.gyp
index df47a2d..1e0155c 100644
--- a/mojo/mojo.gyp
+++ b/mojo/mojo.gyp
@@ -187,6 +187,8 @@
'../base/base.gyp:base',
'../base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations',
'mojo_gles2',
+ 'mojo_gles2_bindings',
+ 'mojo_environment_chromium',
],
'defines': [
'MOJO_GLES2_IMPL_IMPLEMENTATION',
@@ -195,6 +197,8 @@
'gles2/gles2_impl_export.h',
'gles2/gles2_support_impl.cc',
'gles2/gles2_support_impl.h',
+ 'gles2/gles2_client_impl.cc',
+ 'gles2/gles2_client_impl.h',
],
},
{
diff --git a/mojo/mojo_examples.gypi b/mojo/mojo_examples.gypi
index e578329..fd880ef 100644
--- a/mojo/mojo_examples.gypi
+++ b/mojo/mojo_examples.gypi
@@ -14,7 +14,6 @@
'../ui/gl/gl.gyp:gl',
'mojo_environment_standalone',
'mojo_gles2',
- 'mojo_gles2_bindings',
'mojo_native_viewport_bindings',
'mojo_shell_bindings',
'mojo_system',
diff --git a/mojo/public/gles2/gles2.h b/mojo/public/gles2/gles2.h
index 2a6ee11..fbf9fa2 100644
--- a/mojo/public/gles2/gles2.h
+++ b/mojo/public/gles2/gles2.h
@@ -11,16 +11,35 @@
#include <GLES2/gl2.h>
#include "mojo/public/gles2/gles2_export.h"
+#include "mojo/public/gles2/gles2_types.h"
+#include "mojo/public/system/async_waiter.h"
+#include "mojo/public/system/core.h"
#ifdef __cplusplus
extern "C" {
#endif
-MOJO_GLES2_EXPORT void MojoGLES2Initialize();
+MOJO_GLES2_EXPORT void MojoGLES2Initialize(MojoAsyncWaiter* async_waiter);
MOJO_GLES2_EXPORT void MojoGLES2Terminate();
-// TODO(abarth): MojoGLES2MakeCurrent should take a MojoHandle.
-MOJO_GLES2_EXPORT void MojoGLES2MakeCurrent(uint64_t encoded);
+MOJO_GLES2_EXPORT MojoGLES2Context MojoGLES2CreateContext(
+ MojoHandle handle,
+ MojoGLES2ContextCreated created_callback,
+ MojoGLES2ContextLost lost_callback,
+ MojoGLES2DrawAnimationFrame animation_callback,
+ void* closure);
+MOJO_GLES2_EXPORT void MojoGLES2DestroyContext(MojoGLES2Context context);
+MOJO_GLES2_EXPORT void MojoGLES2MakeCurrent(MojoGLES2Context context);
MOJO_GLES2_EXPORT void MojoGLES2SwapBuffers();
+// TODO(piman): this doesn't belong here.
+MOJO_GLES2_EXPORT void MojoGLES2RequestAnimationFrames(
+ MojoGLES2Context context);
+MOJO_GLES2_EXPORT void MojoGLES2CancelAnimationFrames(MojoGLES2Context context);
+
+// TODO(piman): We shouldn't have to leak those 2 interfaces, especially in a
+// type-unsafe way.
+MOJO_GLES2_EXPORT void* MojoGLES2GetGLES2Interface(MojoGLES2Context context);
+MOJO_GLES2_EXPORT void* MojoGLES2GetContextSupport(MojoGLES2Context context);
+
#define VISIT_GL_CALL(Function, ReturnType, PARAMETERS, ARGUMENTS) \
MOJO_GLES2_EXPORT ReturnType GL_APIENTRY gl##Function PARAMETERS;
#include "mojo/public/gles2/gles2_call_visitor_autogen.h"
diff --git a/mojo/public/gles2/gles2_cpp.h b/mojo/public/gles2/gles2_cpp.h
new file mode 100644
index 0000000..fb75731
--- /dev/null
+++ b/mojo/public/gles2/gles2_cpp.h
@@ -0,0 +1,23 @@
+// 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.
+
+#ifndef MOJO_PUBLIC_GLES2_GLES2_CPP_H_
+#define MOJO_PUBLIC_GLES2_GLES2_CPP_H_
+
+#include "mojo/public/environment/default_async_waiter.h"
+#include "mojo/public/gles2/gles2.h"
+
+namespace mojo {
+
+class GLES2Initializer {
+ public:
+ GLES2Initializer(MojoAsyncWaiter* async_waiter = GetDefaultAsyncWaiter()) {
+ MojoGLES2Initialize(async_waiter);
+ }
+ ~GLES2Initializer() { MojoGLES2Terminate(); }
+};
+
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_GLES2_GLES2_H_
diff --git a/mojo/public/gles2/gles2_private.cc b/mojo/public/gles2/gles2_private.cc
index ca873c8..536e0fc 100644
--- a/mojo/public/gles2/gles2_private.cc
+++ b/mojo/public/gles2/gles2_private.cc
@@ -15,9 +15,9 @@ static mojo::GLES2Interface* g_gles2_interface = NULL;
extern "C" {
-void MojoGLES2Initialize() {
+void MojoGLES2Initialize(MojoAsyncWaiter* async_waiter) {
assert(g_gles2_support);
- return g_gles2_support->Initialize();
+ return g_gles2_support->Initialize(async_waiter);
}
void MojoGLES2Terminate() {
@@ -25,9 +25,26 @@ void MojoGLES2Terminate() {
return g_gles2_support->Terminate();
}
-void MojoGLES2MakeCurrent(uint64_t encoded) {
+MojoGLES2Context MojoGLES2CreateContext(
+ MojoHandle handle,
+ MojoGLES2ContextCreated created_callback,
+ MojoGLES2ContextLost lost_callback,
+ MojoGLES2DrawAnimationFrame animation_callback,
+ void* closure) {
+ return g_gles2_support->CreateContext(mojo::MessagePipeHandle(handle),
+ created_callback,
+ lost_callback,
+ animation_callback,
+ closure);
+}
+
+void MojoGLES2DestroyContext(MojoGLES2Context context) {
+ return g_gles2_support->DestroyContext(context);
+}
+
+void MojoGLES2MakeCurrent(MojoGLES2Context context) {
assert(g_gles2_support);
- g_gles2_support->MakeCurrent(encoded);
+ g_gles2_support->MakeCurrent(context);
g_gles2_interface = g_gles2_support->GetGLES2InterfaceForCurrentContext();
}
@@ -36,6 +53,26 @@ void MojoGLES2SwapBuffers() {
return g_gles2_support->SwapBuffers();
}
+void MojoGLES2RequestAnimationFrames(MojoGLES2Context context) {
+ assert(g_gles2_support);
+ return g_gles2_support->RequestAnimationFrames(context);
+}
+
+void MojoGLES2CancelAnimationFrames(MojoGLES2Context context) {
+ assert(g_gles2_support);
+ return g_gles2_support->CancelAnimationFrames(context);
+}
+
+void* MojoGLES2GetGLES2Interface(MojoGLES2Context context) {
+ assert(g_gles2_support);
+ return g_gles2_support->GetGLES2Interface(context);
+}
+
+void* MojoGLES2GetContextSupport(MojoGLES2Context context) {
+ assert(g_gles2_support);
+ return g_gles2_support->GetContextSupport(context);
+}
+
#define VISIT_GL_CALL(Function, ReturnType, PARAMETERS, ARGUMENTS) \
ReturnType gl##Function PARAMETERS { \
return g_gles2_interface->Function ARGUMENTS; \
diff --git a/mojo/public/gles2/gles2_private.h b/mojo/public/gles2/gles2_private.h
index f50f41d..87ea4b9 100644
--- a/mojo/public/gles2/gles2_private.h
+++ b/mojo/public/gles2/gles2_private.h
@@ -8,6 +8,9 @@
#include <stdint.h>
#include "mojo/public/gles2/gles2_export.h"
+#include "mojo/public/gles2/gles2_types.h"
+#include "mojo/public/system/async_waiter.h"
+#include "mojo/public/system/core_cpp.h"
namespace mojo {
class GLES2Interface;
@@ -21,10 +24,21 @@ class MOJO_GLES2_EXPORT GLES2Support {
static void Init(GLES2Support* gles2_support);
- virtual void Initialize() = 0;
+ virtual void Initialize(MojoAsyncWaiter* async_waiter) = 0;
virtual void Terminate() = 0;
- virtual void MakeCurrent(uint64_t encoded) = 0;
+ virtual MojoGLES2Context CreateContext(
+ MessagePipeHandle handle,
+ MojoGLES2ContextCreated created_callback,
+ MojoGLES2ContextLost lost_callback,
+ MojoGLES2DrawAnimationFrame animation_callback,
+ void* closure) = 0;
+ virtual void DestroyContext(MojoGLES2Context context) = 0;
+ virtual void MakeCurrent(MojoGLES2Context context) = 0;
virtual void SwapBuffers() = 0;
+ virtual void RequestAnimationFrames(MojoGLES2Context context) = 0;
+ virtual void CancelAnimationFrames(MojoGLES2Context context) = 0;
+ virtual void* GetGLES2Interface(MojoGLES2Context context) = 0;
+ virtual void* GetContextSupport(MojoGLES2Context context) = 0;
virtual GLES2Interface* GetGLES2InterfaceForCurrentContext() = 0;
};
diff --git a/mojo/public/gles2/gles2_types.h b/mojo/public/gles2/gles2_types.h
new file mode 100644
index 0000000..19c579f
--- /dev/null
+++ b/mojo/public/gles2/gles2_types.h
@@ -0,0 +1,31 @@
+// 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.
+
+#ifndef MOJO_PUBLIC_GLES2_GLES2_TYPES_H_
+#define MOJO_PUBLIC_GLES2_GLES2_TYPES_H_
+
+// Note: This header should be compilable as C.
+
+#include <stdint.h>
+
+#include "mojo/public/gles2/gles2_export.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct MojoGLES2ContextPrivate *MojoGLES2Context;
+// TODO(piman):
+// - create context synchronously
+// - pass width/height through native viewport, not here.
+typedef void (*MojoGLES2ContextCreated)(
+ void* closure, uint32_t width, uint32_t height);
+typedef void (*MojoGLES2ContextLost)(void* closure);
+typedef void (*MojoGLES2DrawAnimationFrame)(void* closure);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // MOJO_PUBLIC_GLES2_GLES2_TYPES_H_