summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsievers@chromium.org <sievers@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-22 18:54:08 +0000
committersievers@chromium.org <sievers@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-22 18:54:08 +0000
commit3a59bb92550acf8bf455007bb482f573a05d9448 (patch)
treeadfb58aacf28aa0a4f4bde2e59df1839d89d4e34
parentb7d060862667150a87fc90939d79aec35a2c0c01 (diff)
downloadchromium_src-3a59bb92550acf8bf455007bb482f573a05d9448.zip
chromium_src-3a59bb92550acf8bf455007bb482f573a05d9448.tar.gz
chromium_src-3a59bb92550acf8bf455007bb482f573a05d9448.tar.bz2
Support stream textures with the synchronous compositor
This adds a thread-safe StreamTextureManager for GLInProcessContext. It further adds some plumbing for the webkit thread to be able to create a StreamTextureFactory from the main thread (see render_view_impl.cc) with the ability to extract the thread-safe SurfaceTexture(Bridge) for a given stream. This is nothing but a crazy amount of plumbing to achieve this: - StreamTexture::Update() i.e. SurfaceTexture::updateTexImage needs to happen on the GL thread with a current context - The StreamTextureFactory and Proxy are referenced from the WebmediaPlayer instance which lives on the main thread - The callback for invalidating the video is posted to the compositor thread directly (here: UI thread) bypassing the main thread BUG=239760 NOTRY=True Review URL: https://chromiumcodereview.appspot.com/23234003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@219057 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--content/browser/android/in_process/synchronous_compositor_impl.cc92
-rw-r--r--content/common/gpu/stream_texture_manager_android.h2
-rw-r--r--content/renderer/android/synchronous_compositor_factory.h3
-rw-r--r--content/renderer/media/android/stream_texture_factory_android_synchronous_impl.cc156
-rw-r--r--content/renderer/media/android/stream_texture_factory_android_synchronous_impl.h29
-rw-r--r--content/renderer/render_view_impl.cc6
-rw-r--r--gpu/command_buffer/client/gl_in_process_context.cc16
-rw-r--r--gpu/command_buffer/client/gl_in_process_context.h11
-rw-r--r--gpu/command_buffer/service/in_process_command_buffer.cc27
-rw-r--r--gpu/command_buffer/service/in_process_command_buffer.h18
-rw-r--r--gpu/command_buffer/service/stream_texture_manager.h4
-rw-r--r--gpu/command_buffer/service/stream_texture_manager_in_process_android.cc92
-rw-r--r--gpu/command_buffer/service/stream_texture_manager_in_process_android.h75
-rw-r--r--gpu/command_buffer/service/stream_texture_manager_mock.h4
-rw-r--r--gpu/command_buffer_service.gypi2
-rw-r--r--webkit/common/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc5
-rw-r--r--webkit/common/gpu/webgraphicscontext3d_in_process_command_buffer_impl.h3
17 files changed, 524 insertions, 21 deletions
diff --git a/content/browser/android/in_process/synchronous_compositor_impl.cc b/content/browser/android/in_process/synchronous_compositor_impl.cc
index 678f622..8fcebf4 100644
--- a/content/browser/android/in_process/synchronous_compositor_impl.cc
+++ b/content/browser/android/in_process/synchronous_compositor_impl.cc
@@ -16,13 +16,20 @@
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/renderer/android/synchronous_compositor_factory.h"
+#include "content/renderer/media/android/stream_texture_factory_android_synchronous_impl.h"
+#include "gpu/command_buffer/client/gl_in_process_context.h"
+#include "gpu/command_buffer/service/stream_texture_manager_in_process_android.h"
+#include "ui/gl/android/surface_texture_bridge.h"
#include "ui/gl/gl_surface.h"
#include "webkit/common/gpu/context_provider_in_process.h"
+#include "webkit/common/gpu/webgraphicscontext3d_in_process_command_buffer_impl.h"
namespace content {
namespace {
+using webkit::gpu::WebGraphicsContext3DInProcessCommandBufferImpl;
+
int GetInProcessRendererId() {
content::RenderProcessHost::iterator it =
content::RenderProcessHost::AllHostsIterator();
@@ -38,9 +45,38 @@ int GetInProcessRendererId() {
return id;
}
+class VideoContextProvider
+ : public StreamTextureFactorySynchronousImpl::ContextProvider {
+ public:
+ VideoContextProvider(
+ const scoped_refptr<cc::ContextProvider>& context_provider,
+ gpu::GLInProcessContext* gl_in_process_context)
+ : context_provider_(context_provider),
+ gl_in_process_context_(gl_in_process_context) {}
+
+ virtual scoped_refptr<gfx::SurfaceTextureBridge> GetSurfaceTexture(
+ uint32 stream_id) OVERRIDE {
+ return gl_in_process_context_->GetSurfaceTexture(stream_id);
+ }
+
+ virtual WebKit::WebGraphicsContext3D* Context3d() OVERRIDE {
+ return context_provider_->Context3d();
+ }
+
+ private:
+ friend class base::RefCountedThreadSafe<VideoContextProvider>;
+ virtual ~VideoContextProvider() {}
+
+ scoped_refptr<cc::ContextProvider> context_provider_;
+ gpu::GLInProcessContext* gl_in_process_context_;
+
+ DISALLOW_COPY_AND_ASSIGN(VideoContextProvider);
+};
+
class SynchronousCompositorFactoryImpl : public SynchronousCompositorFactory {
public:
- SynchronousCompositorFactoryImpl() {
+ SynchronousCompositorFactoryImpl()
+ : wrapped_gl_context_for_main_thread_(NULL) {
SynchronousCompositorFactory::SetInstance(this);
}
@@ -65,15 +101,52 @@ class SynchronousCompositorFactoryImpl : public SynchronousCompositorFactory {
return &synchronous_input_event_filter_;
}
+ scoped_ptr<WebGraphicsContext3DInProcessCommandBufferImpl>
+ CreateOffscreenContext() {
+ if (!gfx::GLSurface::InitializeOneOff())
+ return scoped_ptr<WebGraphicsContext3DInProcessCommandBufferImpl>();
+
+ const char* allowed_extensions = "*";
+ const gfx::GpuPreference gpu_preference = gfx::PreferDiscreteGpu;
+
+ WebKit::WebGraphicsContext3D::Attributes attributes;
+ attributes.antialias = false;
+ attributes.shareResources = true;
+ attributes.noAutomaticFlushes = true;
+
+ gpu::GLInProcessContextAttribs in_process_attribs;
+ WebGraphicsContext3DInProcessCommandBufferImpl::ConvertAttributes(
+ attributes, &in_process_attribs);
+ scoped_ptr<gpu::GLInProcessContext> context(
+ gpu::GLInProcessContext::CreateContext(true,
+ NULL,
+ gfx::Size(1, 1),
+ attributes.shareResources,
+ allowed_extensions,
+ in_process_attribs,
+ gpu_preference));
+
+ wrapped_gl_context_for_main_thread_ = context.get();
+ if (!context.get())
+ return scoped_ptr<WebGraphicsContext3DInProcessCommandBufferImpl>();
+
+ return scoped_ptr<WebGraphicsContext3DInProcessCommandBufferImpl>(
+ WebGraphicsContext3DInProcessCommandBufferImpl::WrapContext(
+ context.Pass(), attributes));
+ }
+
virtual scoped_refptr<cc::ContextProvider>
GetOffscreenContextProviderForMainThread() OVERRIDE {
if (!offscreen_context_for_main_thread_.get() ||
offscreen_context_for_main_thread_->DestroyedOnMainThread()) {
offscreen_context_for_main_thread_ =
- webkit::gpu::ContextProviderInProcess::CreateOffscreen();
+ webkit::gpu::ContextProviderInProcess::Create(
+ CreateOffscreenContext());
if (offscreen_context_for_main_thread_.get() &&
- !offscreen_context_for_main_thread_->BindToCurrentThread())
+ !offscreen_context_for_main_thread_->BindToCurrentThread()) {
offscreen_context_for_main_thread_ = NULL;
+ wrapped_gl_context_for_main_thread_ = NULL;
+ }
}
return offscreen_context_for_main_thread_;
}
@@ -95,6 +168,16 @@ class SynchronousCompositorFactoryImpl : public SynchronousCompositorFactory {
return offscreen_context_for_compositor_thread_;
}
+ virtual scoped_ptr<StreamTextureFactory> CreateStreamTextureFactory(
+ int view_id) OVERRIDE {
+ scoped_refptr<VideoContextProvider> context_provider =
+ new VideoContextProvider(offscreen_context_for_main_thread_,
+ wrapped_gl_context_for_main_thread_);
+ return make_scoped_ptr(new StreamTextureFactorySynchronousImpl(
+ context_provider.get(), view_id))
+ .PassAs<StreamTextureFactory>();
+ }
+
private:
SynchronousInputEventFilter synchronous_input_event_filter_;
@@ -102,6 +185,9 @@ class SynchronousCompositorFactoryImpl : public SynchronousCompositorFactory {
// not usage.
base::Lock offscreen_context_for_compositor_thread_creation_lock_;
scoped_refptr<cc::ContextProvider> offscreen_context_for_main_thread_;
+ // This is a pointer to the context owned by
+ // |offscreen_context_for_main_thread_|.
+ gpu::GLInProcessContext* wrapped_gl_context_for_main_thread_;
scoped_refptr<cc::ContextProvider> offscreen_context_for_compositor_thread_;
};
diff --git a/content/common/gpu/stream_texture_manager_android.h b/content/common/gpu/stream_texture_manager_android.h
index 9421d6a..9da84d9 100644
--- a/content/common/gpu/stream_texture_manager_android.h
+++ b/content/common/gpu/stream_texture_manager_android.h
@@ -30,7 +30,7 @@ class StreamTextureManagerAndroid : public gpu::StreamTextureManager {
virtual ~StreamTextureManagerAndroid();
// implement gpu::StreamTextureManager:
- virtual GLuint CreateStreamTexture(uint32 service_id,
+ virtual uint32 CreateStreamTexture(uint32 service_id,
uint32 client_id) OVERRIDE;
virtual void DestroyStreamTexture(uint32 service_id) OVERRIDE;
virtual gpu::StreamTexture* LookupStreamTexture(uint32 service_id) OVERRIDE;
diff --git a/content/renderer/android/synchronous_compositor_factory.h b/content/renderer/android/synchronous_compositor_factory.h
index 234a033..bd625be 100644
--- a/content/renderer/android/synchronous_compositor_factory.h
+++ b/content/renderer/android/synchronous_compositor_factory.h
@@ -20,6 +20,7 @@ class OutputSurface;
namespace content {
class InputHandlerManagerClient;
+class StreamTextureFactory;
// Decouples creation from usage of the parts needed for the synchonous
// compositor rendering path. In practice this is only used in single
@@ -44,6 +45,8 @@ class SynchronousCompositorFactory {
GetOffscreenContextProviderForMainThread() = 0;
virtual scoped_refptr<cc::ContextProvider>
GetOffscreenContextProviderForCompositorThread() = 0;
+ virtual scoped_ptr<StreamTextureFactory> CreateStreamTextureFactory(
+ int view_id) = 0;
protected:
SynchronousCompositorFactory() {}
diff --git a/content/renderer/media/android/stream_texture_factory_android_synchronous_impl.cc b/content/renderer/media/android/stream_texture_factory_android_synchronous_impl.cc
index 88878d5..de0ca92 100644
--- a/content/renderer/media/android/stream_texture_factory_android_synchronous_impl.cc
+++ b/content/renderer/media/android/stream_texture_factory_android_synchronous_impl.cc
@@ -4,31 +4,175 @@
#include "content/renderer/media/android/stream_texture_factory_android_synchronous_impl.h"
+#include <algorithm>
+
+#include "base/bind.h"
+#include "base/callback.h"
+#include "base/location.h"
+#include "base/memory/weak_ptr.h"
+#include "base/message_loop/message_loop_proxy.h"
+#include "base/process/process.h"
+#include "base/synchronization/lock.h"
+#include "cc/output/context_provider.h"
+#include "content/common/android/surface_texture_peer.h"
+#include "third_party/WebKit/public/platform/WebGraphicsContext3D.h"
+#include "ui/gl/android/surface_texture_bridge.h"
+
namespace content {
-StreamTextureFactorySynchronousImpl::StreamTextureFactorySynchronousImpl() {}
+namespace {
+
+class StreamTextureProxyImpl
+ : public StreamTextureProxy,
+ public base::SupportsWeakPtr<StreamTextureProxyImpl> {
+ public:
+ explicit StreamTextureProxyImpl(
+ StreamTextureFactorySynchronousImpl::ContextProvider* provider);
+ virtual ~StreamTextureProxyImpl();
+
+ // StreamTextureProxy implementation:
+ virtual void BindToCurrentThread(int32 stream_id) OVERRIDE;
+ virtual bool IsBoundToThread() OVERRIDE { return loop_.get() != NULL; }
+ virtual void SetClient(cc::VideoFrameProvider::Client* client) OVERRIDE;
+ virtual void Release() OVERRIDE;
+
+ private:
+ void OnFrameAvailable();
+
+ scoped_refptr<base::MessageLoopProxy> loop_;
+ base::Lock client_lock_;
+ cc::VideoFrameProvider::Client* client_;
+ base::Closure callback_;
+
+ scoped_refptr<StreamTextureFactorySynchronousImpl::ContextProvider>
+ context_provider_;
+ scoped_refptr<gfx::SurfaceTextureBridge> surface_texture_;
+
+ float current_matrix_[16];
+ bool has_updated_;
+
+ DISALLOW_IMPLICIT_CONSTRUCTORS(StreamTextureProxyImpl);
+};
+
+StreamTextureProxyImpl::StreamTextureProxyImpl(
+ StreamTextureFactorySynchronousImpl::ContextProvider* provider)
+ : context_provider_(provider), has_updated_(false) {
+ std::fill(current_matrix_, current_matrix_ + 16, 0);
+}
+
+StreamTextureProxyImpl::~StreamTextureProxyImpl() {}
+
+void StreamTextureProxyImpl::Release() {
+ SetClient(NULL);
+ if (!loop_->BelongsToCurrentThread())
+ loop_->DeleteSoon(FROM_HERE, this);
+ else
+ delete this;
+}
+
+void StreamTextureProxyImpl::SetClient(cc::VideoFrameProvider::Client* client) {
+ base::AutoLock lock(client_lock_);
+ client_ = client;
+}
+
+void StreamTextureProxyImpl::BindToCurrentThread(int stream_id) {
+ loop_ = base::MessageLoopProxy::current();
+
+ surface_texture_ = context_provider_->GetSurfaceTexture(stream_id);
+ if (!surface_texture_) {
+ LOG(ERROR) << "Failed to get SurfaceTexture for stream.";
+ return;
+ }
+
+ callback_ =
+ base::Bind(&StreamTextureProxyImpl::OnFrameAvailable, AsWeakPtr());
+ surface_texture_->SetFrameAvailableCallback(callback_);
+}
+
+void StreamTextureProxyImpl::OnFrameAvailable() {
+ // GetTransformMatrix only returns something valid after both is true:
+ // - OnFrameAvailable was called
+ // - we called UpdateTexImage
+ if (has_updated_) {
+ float matrix[16];
+ surface_texture_->GetTransformMatrix(matrix);
+
+ if (memcmp(current_matrix_, matrix, sizeof(matrix)) != 0) {
+ memcpy(current_matrix_, matrix, sizeof(matrix));
+
+ base::AutoLock lock(client_lock_);
+ if (client_)
+ client_->DidUpdateMatrix(current_matrix_);
+ }
+ }
+ // OnFrameAvailable being called a second time implies that we called
+ // updateTexImage since after we received the first frame.
+ has_updated_ = true;
+
+ base::AutoLock lock(client_lock_);
+ if (client_)
+ client_->DidReceiveFrame();
+}
+
+} // namespace
+
+StreamTextureFactorySynchronousImpl::StreamTextureFactorySynchronousImpl(
+ ContextProvider* context_provider,
+ int view_id)
+ : context_provider_(context_provider), view_id_(view_id) {}
+
StreamTextureFactorySynchronousImpl::~StreamTextureFactorySynchronousImpl() {}
StreamTextureProxy* StreamTextureFactorySynchronousImpl::CreateProxy() {
- return NULL;
+ return new StreamTextureProxyImpl(context_provider_);
}
void StreamTextureFactorySynchronousImpl::EstablishPeer(int32 stream_id,
- int player_id) {}
+ int player_id) {
+ scoped_refptr<gfx::SurfaceTextureBridge> surface_texture =
+ context_provider_->GetSurfaceTexture(stream_id);
+ if (surface_texture) {
+ SurfaceTexturePeer::GetInstance()->EstablishSurfaceTexturePeer(
+ base::Process::Current().handle(),
+ surface_texture,
+ view_id_,
+ player_id);
+ }
+}
unsigned StreamTextureFactorySynchronousImpl::CreateStreamTexture(
unsigned texture_target,
unsigned* texture_id,
gpu::Mailbox* texture_mailbox,
unsigned* texture_mailbox_sync_point) {
- return 0;
+ WebKit::WebGraphicsContext3D* context = context_provider_->Context3d();
+ unsigned stream_id = 0;
+ if (context->makeContextCurrent()) {
+ *texture_id = context->createTexture();
+ stream_id = context->createStreamTextureCHROMIUM(*texture_id);
+
+ context->genMailboxCHROMIUM(texture_mailbox->name);
+ context->bindTexture(texture_target, *texture_id);
+ context->produceTextureCHROMIUM(texture_target, texture_mailbox->name);
+
+ context->flush();
+ *texture_mailbox_sync_point = context->insertSyncPoint();
+ }
+ return stream_id;
}
void StreamTextureFactorySynchronousImpl::DestroyStreamTexture(
- unsigned texture_id) {}
+ unsigned texture_id) {
+ WebKit::WebGraphicsContext3D* context = context_provider_->Context3d();
+ if (context->makeContextCurrent()) {
+ context->destroyStreamTextureCHROMIUM(texture_id);
+ context->deleteTexture(texture_id);
+ context->flush();
+ }
+}
void StreamTextureFactorySynchronousImpl::SetStreamTextureSize(
- int32 texture_id,
+ int32 stream_id,
const gfx::Size& size) {}
} // namespace content
diff --git a/content/renderer/media/android/stream_texture_factory_android_synchronous_impl.h b/content/renderer/media/android/stream_texture_factory_android_synchronous_impl.h
index 52fc65a..50f9e80 100644
--- a/content/renderer/media/android/stream_texture_factory_android_synchronous_impl.h
+++ b/content/renderer/media/android/stream_texture_factory_android_synchronous_impl.h
@@ -5,14 +5,36 @@
#ifndef CONTENT_RENDERER_MEDIA_ANDROID_STREAM_TEXTURE_FACTORY_ANDROID_SYNCHRONOUS_IMPL_H_
#define CONTENT_RENDERER_MEDIA_ANDROID_STREAM_TEXTURE_FACTORY_ANDROID_SYNCHRONOUS_IMPL_H_
+#include "base/memory/ref_counted.h"
#include "content/renderer/media/android/stream_texture_factory_android.h"
+namespace gfx {
+class SurfaceTextureBridge;
+}
+
+namespace WebKit {
+class WebGraphicsContext3D;
+}
+
namespace content {
// Factory for when using synchronous compositor in Android WebView.
class StreamTextureFactorySynchronousImpl : public StreamTextureFactory {
public:
- StreamTextureFactorySynchronousImpl();
+ class ContextProvider : public base::RefCountedThreadSafe<ContextProvider> {
+ public:
+ virtual scoped_refptr<gfx::SurfaceTextureBridge> GetSurfaceTexture(
+ uint32 stream_id) = 0;
+
+ virtual WebKit::WebGraphicsContext3D* Context3d() = 0;
+
+ protected:
+ friend class base::RefCountedThreadSafe<ContextProvider>;
+ virtual ~ContextProvider() {}
+ };
+
+ StreamTextureFactorySynchronousImpl(ContextProvider* context_provider,
+ int view_id);
virtual ~StreamTextureFactorySynchronousImpl();
virtual StreamTextureProxy* CreateProxy() OVERRIDE;
@@ -23,10 +45,13 @@ class StreamTextureFactorySynchronousImpl : public StreamTextureFactory {
gpu::Mailbox* texture_mailbox,
unsigned* texture_mailbox_sync_point) OVERRIDE;
virtual void DestroyStreamTexture(unsigned texture_id) OVERRIDE;
- virtual void SetStreamTextureSize(int32 texture_id,
+ virtual void SetStreamTextureSize(int32 stream_id,
const gfx::Size& size) OVERRIDE;
private:
+ scoped_refptr<ContextProvider> context_provider_;
+ int view_id_;
+
DISALLOW_COPY_AND_ASSIGN(StreamTextureFactorySynchronousImpl);
};
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc
index 5bde8ba..32f323f 100644
--- a/content/renderer/render_view_impl.cc
+++ b/content/renderer/render_view_impl.cc
@@ -212,9 +212,9 @@
#include "content/renderer/android/content_detector.h"
#include "content/renderer/android/email_detector.h"
#include "content/renderer/android/phone_number_detector.h"
+#include "content/renderer/android/synchronous_compositor_factory.h"
#include "content/renderer/media/android/renderer_media_player_manager.h"
#include "content/renderer/media/android/stream_texture_factory_android_impl.h"
-#include "content/renderer/media/android/stream_texture_factory_android_synchronous_impl.h"
#include "content/renderer/media/android/webmediaplayer_android.h"
#include "content/renderer/media/android/webmediaplayer_proxy_android.h"
#include "skia/ext/platform_canvas.h"
@@ -3037,7 +3037,9 @@ WebMediaPlayer* RenderViewImpl::createMediaPlayer(
scoped_ptr<StreamTextureFactory> stream_texture_factory;
if (UsingSynchronousRendererCompositor()) {
- stream_texture_factory.reset(new StreamTextureFactorySynchronousImpl);
+ SynchronousCompositorFactory* factory =
+ SynchronousCompositorFactory::GetInstance();
+ stream_texture_factory = factory->CreateStreamTextureFactory(routing_id_);
} else {
stream_texture_factory.reset(new StreamTextureFactoryImpl(
context_provider->Context3d(), gpu_channel_host, routing_id_));
diff --git a/gpu/command_buffer/client/gl_in_process_context.cc b/gpu/command_buffer/client/gl_in_process_context.cc
index f97099a..984214d 100644
--- a/gpu/command_buffer/client/gl_in_process_context.cc
+++ b/gpu/command_buffer/client/gl_in_process_context.cc
@@ -30,6 +30,10 @@
#include "ui/gfx/size.h"
#include "ui/gl/gl_image.h"
+#if defined(OS_ANDROID)
+#include "ui/gl/android/surface_texture_bridge.h"
+#endif
+
namespace gpu {
namespace {
@@ -65,6 +69,11 @@ class GLInProcessContextImpl
OVERRIDE;
virtual gles2::GLES2Implementation* GetImplementation() OVERRIDE;
+#if defined(OS_ANDROID)
+ virtual scoped_refptr<gfx::SurfaceTextureBridge> GetSurfaceTexture(
+ uint32 stream_id) OVERRIDE;
+#endif
+
private:
void Destroy();
void PollQueryCallbacks();
@@ -333,6 +342,13 @@ void GLInProcessContextImpl::SignalQuery(
}
}
+#if defined(OS_ANDROID)
+scoped_refptr<gfx::SurfaceTextureBridge>
+GLInProcessContextImpl::GetSurfaceTexture(uint32 stream_id) {
+ return command_buffer_->GetSurfaceTexture(stream_id);
+}
+#endif
+
} // anonymous namespace
GLInProcessContextAttribs::GLInProcessContextAttribs()
diff --git a/gpu/command_buffer/client/gl_in_process_context.h b/gpu/command_buffer/client/gl_in_process_context.h
index 7e924b5..ec7bdc5 100644
--- a/gpu/command_buffer/client/gl_in_process_context.h
+++ b/gpu/command_buffer/client/gl_in_process_context.h
@@ -16,6 +16,12 @@ namespace gfx {
class Size;
}
+#if defined(OS_ANDROID)
+namespace gfx {
+class SurfaceTextureBridge;
+}
+#endif
+
namespace gpu {
namespace gles2 {
@@ -73,6 +79,11 @@ class GLES2_IMPL_EXPORT GLInProcessContext {
// Allows direct access to the GLES2 implementation so a GLInProcessContext
// can be used without making it current.
virtual gles2::GLES2Implementation* GetImplementation() = 0;
+
+#if defined(OS_ANDROID)
+ virtual scoped_refptr<gfx::SurfaceTextureBridge> GetSurfaceTexture(
+ uint32 stream_id) = 0;
+#endif
};
} // namespace gpu
diff --git a/gpu/command_buffer/service/in_process_command_buffer.cc b/gpu/command_buffer/service/in_process_command_buffer.cc
index 2f949c9..6b9fe8a 100644
--- a/gpu/command_buffer/service/in_process_command_buffer.cc
+++ b/gpu/command_buffer/service/in_process_command_buffer.cc
@@ -34,6 +34,11 @@
#include "ui/gl/gl_image.h"
#include "ui/gl/gl_share_group.h"
+#if defined(OS_ANDROID)
+#include "gpu/command_buffer/service/stream_texture_manager_in_process_android.h"
+#include "ui/gl/android/surface_texture_bridge.h"
+#endif
+
namespace gpu {
namespace {
@@ -379,11 +384,21 @@ bool InProcessCommandBuffer::InitializeOnGpuThread(
share_group = new gfx::GLShareGroup;
}
+ StreamTextureManager* stream_texture_manager = NULL;
+#if defined(OS_ANDROID)
+ stream_texture_manager = stream_texture_manager_ =
+ context_group ? context_group->stream_texture_manager_.get()
+ : new StreamTextureManagerInProcess;
+#endif
+
bool bind_generates_resource = false;
decoder_.reset(gles2::GLES2Decoder::Create(
context_group ? context_group->decoder_->GetContextGroup()
- : new gles2::ContextGroup(
- NULL, NULL, NULL, NULL, bind_generates_resource)));
+ : new gles2::ContextGroup(NULL,
+ NULL,
+ NULL,
+ stream_texture_manager,
+ bind_generates_resource)));
gpu_scheduler_.reset(
new GpuScheduler(command_buffer.get(), decoder_.get(), decoder_.get()));
@@ -712,6 +727,14 @@ base::Closure InProcessCommandBuffer::WrapCallback(
return wrapped_callback;
}
+#if defined(OS_ANDROID)
+scoped_refptr<gfx::SurfaceTextureBridge>
+InProcessCommandBuffer::GetSurfaceTexture(uint32 stream_id) {
+ DCHECK(stream_texture_manager_);
+ return stream_texture_manager_->GetSurfaceTexture(stream_id);
+}
+#endif
+
// static
void InProcessCommandBuffer::EnableVirtualizedContext() {
g_use_virtualized_gl_context = true;
diff --git a/gpu/command_buffer/service/in_process_command_buffer.h b/gpu/command_buffer/service/in_process_command_buffer.h
index 03c0f42..3caf4aa 100644
--- a/gpu/command_buffer/service/in_process_command_buffer.h
+++ b/gpu/command_buffer/service/in_process_command_buffer.h
@@ -31,6 +31,15 @@ class GLSurface;
class Size;
}
+#if defined(OS_ANDROID)
+namespace gfx {
+class SurfaceTextureBridge;
+}
+namespace gpu {
+class StreamTextureManagerInProcess;
+}
+#endif
+
namespace gpu {
namespace gles2 {
@@ -116,6 +125,11 @@ class GPU_EXPORT InProcessCommandBuffer : public CommandBuffer,
virtual void QueueTask(const base::Closure& task) = 0;
};
+#if defined(OS_ANDROID)
+ scoped_refptr<gfx::SurfaceTextureBridge> GetSurfaceTexture(
+ uint32 stream_id);
+#endif
+
private:
bool InitializeOnGpuThread(bool is_offscreen,
gfx::AcceleratedWidget window,
@@ -163,6 +177,10 @@ class GPU_EXPORT InProcessCommandBuffer : public CommandBuffer,
base::Lock state_after_last_flush_lock_;
scoped_ptr<GpuControl> gpu_control_;
+#if defined(OS_ANDROID)
+ scoped_refptr<StreamTextureManagerInProcess> stream_texture_manager_;
+#endif
+
// Only used with explicit scheduling and the gpu thread is the same as
// the client thread.
scoped_ptr<base::SequenceChecker> sequence_checker_;
diff --git a/gpu/command_buffer/service/stream_texture_manager.h b/gpu/command_buffer/service/stream_texture_manager.h
index b4f0a53..51119fa 100644
--- a/gpu/command_buffer/service/stream_texture_manager.h
+++ b/gpu/command_buffer/service/stream_texture_manager.h
@@ -6,7 +6,6 @@
#define GPU_COMMAND_BUFFER_SERVICE_STREAM_TEXTURE_MANAGER_H_
#include "base/basictypes.h"
-#include "gpu/command_buffer/service/gl_utils.h"
namespace gpu {
@@ -22,8 +21,7 @@ class StreamTextureManager {
}
// Returns an identifier for the object, or NULL if not successful.
- virtual GLuint CreateStreamTexture(uint32 service_id,
- uint32 client_id) = 0;
+ virtual uint32 CreateStreamTexture(uint32 service_id, uint32 client_id) = 0;
virtual void DestroyStreamTexture(uint32 service_id) = 0;
diff --git a/gpu/command_buffer/service/stream_texture_manager_in_process_android.cc b/gpu/command_buffer/service/stream_texture_manager_in_process_android.cc
new file mode 100644
index 0000000..0a6c4c9
--- /dev/null
+++ b/gpu/command_buffer/service/stream_texture_manager_in_process_android.cc
@@ -0,0 +1,92 @@
+// Copyright 2013 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 "gpu/command_buffer/service/stream_texture_manager_in_process_android.h"
+
+#include "base/bind.h"
+#include "ui/gfx/size.h"
+#include "ui/gl/android/surface_texture_bridge.h"
+#include "ui/gl/gl_bindings.h"
+
+namespace gpu {
+
+StreamTextureManagerInProcess::StreamTextureImpl::StreamTextureImpl(
+ uint32 service_id,
+ uint32 stream_id)
+ : surface_texture_bridge_(new gfx::SurfaceTextureBridge(service_id)),
+ stream_id_(stream_id) {}
+
+StreamTextureManagerInProcess::StreamTextureImpl::~StreamTextureImpl() {}
+
+void StreamTextureManagerInProcess::StreamTextureImpl::Update() {
+ GLint texture_id = 0;
+ glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &texture_id);
+ surface_texture_bridge_->UpdateTexImage();
+ glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture_id);
+}
+
+gfx::Size StreamTextureManagerInProcess::StreamTextureImpl::GetSize() {
+ return size_;
+}
+
+void StreamTextureManagerInProcess::StreamTextureImpl::SetSize(gfx::Size size) {
+ size_ = size;
+}
+
+scoped_refptr<gfx::SurfaceTextureBridge>
+StreamTextureManagerInProcess::StreamTextureImpl::GetSurfaceTexture() {
+ return surface_texture_bridge_;
+}
+
+StreamTextureManagerInProcess::StreamTextureManagerInProcess() : next_id_(1) {}
+
+StreamTextureManagerInProcess::~StreamTextureManagerInProcess() {
+ if (!textures_.empty()) {
+ LOG(WARNING) << "Undestroyed surface textures while tearing down "
+ "StreamTextureManager.";
+ }
+}
+
+GLuint StreamTextureManagerInProcess::CreateStreamTexture(uint32 service_id,
+ uint32 client_id) {
+ base::AutoLock lock(map_lock_);
+ uint32 stream_id = next_id_++;
+ linked_ptr<StreamTextureImpl> texture(
+ new StreamTextureImpl(service_id, stream_id));
+ textures_[service_id] = texture;
+
+ if (next_id_ == 0)
+ next_id_++;
+
+ return stream_id;
+}
+
+void StreamTextureManagerInProcess::DestroyStreamTexture(uint32 service_id) {
+ base::AutoLock lock(map_lock_);
+ textures_.erase(service_id);
+}
+
+gpu::StreamTexture* StreamTextureManagerInProcess::LookupStreamTexture(
+ uint32 service_id) {
+ base::AutoLock lock(map_lock_);
+ TextureMap::const_iterator it = textures_.find(service_id);
+ if (it != textures_.end())
+ return it->second.get();
+
+ return NULL;
+}
+
+scoped_refptr<gfx::SurfaceTextureBridge>
+StreamTextureManagerInProcess::GetSurfaceTexture(uint32 stream_id) {
+ base::AutoLock lock(map_lock_);
+ for (TextureMap::iterator it = textures_.begin(); it != textures_.end();
+ it++) {
+ if (it->second->stream_id() == stream_id)
+ return it->second->GetSurfaceTexture();
+ }
+
+ return NULL;
+}
+
+} // namespace gpu
diff --git a/gpu/command_buffer/service/stream_texture_manager_in_process_android.h b/gpu/command_buffer/service/stream_texture_manager_in_process_android.h
new file mode 100644
index 0000000..70ec024
--- /dev/null
+++ b/gpu/command_buffer/service/stream_texture_manager_in_process_android.h
@@ -0,0 +1,75 @@
+// Copyright 2013 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 GPU_STREAM_TEXTURE_MANAGER_IN_PROCESS_ANDROID_H_
+#define GPU_STREAM_TEXTURE_MANAGER_IN_PROCESS_ANDROID_H_
+
+#include <map>
+
+#include "base/memory/linked_ptr.h"
+#include "base/memory/ref_counted.h"
+#include "base/synchronization/lock.h"
+#include "gpu/command_buffer/service/stream_texture.h"
+#include "gpu/command_buffer/service/stream_texture_manager.h"
+
+namespace gfx {
+class Size;
+class SurfaceTextureBridge;
+}
+
+namespace gpu {
+
+class StreamTextureManagerInProcess
+ : public gpu::StreamTextureManager,
+ public base::RefCountedThreadSafe<StreamTextureManagerInProcess> {
+ public:
+ StreamTextureManagerInProcess();
+
+ // implement gpu::StreamTextureManager:
+ virtual uint32 CreateStreamTexture(uint32 service_id,
+ uint32 client_id) OVERRIDE;
+ virtual void DestroyStreamTexture(uint32 service_id) OVERRIDE;
+ virtual gpu::StreamTexture* LookupStreamTexture(uint32 service_id) OVERRIDE;
+
+ scoped_refptr<gfx::SurfaceTextureBridge> GetSurfaceTexture(uint32 stream_id);
+
+ private:
+ class StreamTextureImpl : public gpu::StreamTexture {
+ public:
+ StreamTextureImpl(uint32 service_id, uint32 stream_id);
+ virtual ~StreamTextureImpl();
+
+ // implement gpu::StreamTexture
+ virtual void Update() OVERRIDE;
+ virtual gfx::Size GetSize() OVERRIDE;
+
+ void SetSize(gfx::Size size);
+
+ scoped_refptr<gfx::SurfaceTextureBridge> GetSurfaceTexture();
+ uint32 stream_id() { return stream_id_; }
+
+ private:
+ scoped_refptr<gfx::SurfaceTextureBridge> surface_texture_bridge_;
+ uint32 stream_id_;
+ gfx::Size size_;
+
+ DISALLOW_COPY_AND_ASSIGN(StreamTextureImpl);
+ };
+
+ friend class base::RefCountedThreadSafe<StreamTextureManagerInProcess>;
+ virtual ~StreamTextureManagerInProcess();
+
+ typedef std::map<uint32, linked_ptr<StreamTextureImpl> > TextureMap;
+ TextureMap textures_;
+
+ uint32 next_id_;
+
+ base::Lock map_lock_;
+
+ DISALLOW_COPY_AND_ASSIGN(StreamTextureManagerInProcess);
+};
+
+} // gpu
+
+#endif // GPU_STREAM_TEXTURE_MANAGER_IN_PROCESS_ANDROID_H_
diff --git a/gpu/command_buffer/service/stream_texture_manager_mock.h b/gpu/command_buffer/service/stream_texture_manager_mock.h
index ac145ec..4b744f2 100644
--- a/gpu/command_buffer/service/stream_texture_manager_mock.h
+++ b/gpu/command_buffer/service/stream_texture_manager_mock.h
@@ -18,8 +18,8 @@ class MockStreamTextureManager : public StreamTextureManager {
MockStreamTextureManager();
virtual ~MockStreamTextureManager();
- MOCK_METHOD2(CreateStreamTexture, GLuint(uint32 service_id,
- uint32 client_id));
+ MOCK_METHOD2(CreateStreamTexture,
+ uint32(uint32 service_id, uint32 client_id));
MOCK_METHOD1(DestroyStreamTexture, void(uint32 service_id));
MOCK_METHOD1(LookupStreamTexture, StreamTexture*(uint32 service_id));
diff --git a/gpu/command_buffer_service.gypi b/gpu/command_buffer_service.gypi
index d9408b6..9c9c3f7 100644
--- a/gpu/command_buffer_service.gypi
+++ b/gpu/command_buffer_service.gypi
@@ -116,6 +116,8 @@
'command_buffer/service/shader_translator_cache.cc',
'command_buffer/service/stream_texture.h',
'command_buffer/service/stream_texture_manager.h',
+ 'command_buffer/service/stream_texture_manager_in_process_android.h',
+ 'command_buffer/service/stream_texture_manager_in_process_android.cc',
'command_buffer/service/texture_manager.h',
'command_buffer/service/texture_manager.cc',
'command_buffer/service/transfer_buffer_manager.cc',
diff --git a/webkit/common/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc b/webkit/common/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc
index 66c7a53..9207ef9 100644
--- a/webkit/common/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc
+++ b/webkit/common/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc
@@ -1117,6 +1117,11 @@ DELEGATE_TO_GL_2(bindTexImage2DCHROMIUM, BindTexImage2DCHROMIUM,
DELEGATE_TO_GL_2(releaseTexImage2DCHROMIUM, ReleaseTexImage2DCHROMIUM,
WGC3Denum, WGC3Dint)
+DELEGATE_TO_GL_1R(createStreamTextureCHROMIUM, CreateStreamTextureCHROMIUM,
+ WebGLId, WebGLId)
+DELEGATE_TO_GL_1(destroyStreamTextureCHROMIUM, DestroyStreamTextureCHROMIUM,
+ WebGLId)
+
void* WebGraphicsContext3DInProcessCommandBufferImpl::mapBufferCHROMIUM(
WGC3Denum target, WGC3Denum access) {
ClearContext();
diff --git a/webkit/common/gpu/webgraphicscontext3d_in_process_command_buffer_impl.h b/webkit/common/gpu/webgraphicscontext3d_in_process_command_buffer_impl.h
index f96607d..d763e14 100644
--- a/webkit/common/gpu/webgraphicscontext3d_in_process_command_buffer_impl.h
+++ b/webkit/common/gpu/webgraphicscontext3d_in_process_command_buffer_impl.h
@@ -468,6 +468,9 @@ class WEBKIT_GPU_EXPORT WebGraphicsContext3DInProcessCommandBufferImpl
virtual void bindTexImage2DCHROMIUM(WGC3Denum target, WGC3Dint imageId);
virtual void releaseTexImage2DCHROMIUM(WGC3Denum target, WGC3Dint imageId);
+ virtual WebGLId createStreamTextureCHROMIUM(WebGLId texture);
+ virtual void destroyStreamTextureCHROMIUM(WebGLId texture);
+
virtual void texStorage2DEXT(
WGC3Denum target, WGC3Dint levels, WGC3Duint internalformat,
WGC3Dint width, WGC3Dint height);