Index: content/common/gpu/gpu_channel_manager.cc |
diff --git a/content/common/gpu/gpu_channel_manager.cc b/content/common/gpu/gpu_channel_manager.cc |
index 86ea2bf7de6ef5e59797c192213f808698e3d957..8dd806a9b14f65b8a688cbcdd0f67c8618e570a1 100644 |
--- a/content/common/gpu/gpu_channel_manager.cc |
+++ b/content/common/gpu/gpu_channel_manager.cc |
@@ -18,8 +18,92 @@ |
#include "ui/gl/gl_bindings.h" |
#include "ui/gl/gl_share_group.h" |
+#if defined(OS_ANDROID) |
+#include "base/containers/scoped_ptr_hash_map.h" |
+#include "base/lazy_instance.h" |
+#include "ui/gl/android/scoped_java_surface.h" |
+#include "ui/gl/android/surface_texture.h" |
+#include "ui/gl/android/surface_texture_tracker.h" |
+#endif |
+ |
namespace content { |
+#if defined(OS_ANDROID) |
+namespace { |
+ |
+class SurfaceTextureTrackerImpl : public gfx::SurfaceTextureTracker { |
+ public: |
+ SurfaceTextureTrackerImpl() { |
+ thread_checker_.DetachFromThread(); |
+ } |
+ |
+ // Overridden from gfx::SurfaceTextureTracker: |
+ virtual scoped_refptr<gfx::SurfaceTexture> AcquireSurfaceTexture( |
+ int primary_id, |
+ int secondary_id) OVERRIDE { |
+ base::AutoLock lock(surface_textures_lock_); |
+ scoped_ptr<SurfaceTextureInfo> info = |
+ surface_textures_.take_and_erase(SurfaceTextureMapKey( |
+ primary_id, static_cast<base::ProcessHandle>(secondary_id))); |
+ return info ? info->surface_texture : NULL; |
+ } |
+ |
+ void AddSurfaceTexture(gfx::SurfaceTexture* surface_texture, |
+ int surface_texture_id, |
+ base::ProcessHandle process_handle) { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ base::AutoLock lock(surface_textures_lock_); |
+ SurfaceTextureMapKey key(surface_texture_id, process_handle); |
+ DCHECK(surface_textures_.find(key) == surface_textures_.end()); |
+ surface_textures_.set( |
+ key, make_scoped_ptr(new SurfaceTextureInfo(surface_texture))); |
+ } |
+ |
+ void RemoveAllSurfaceTextures(base::ProcessHandle process_handle) { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ base::AutoLock lock(surface_textures_lock_); |
+ SurfaceTextureMap::iterator it = surface_textures_.begin(); |
+ while (it != surface_textures_.end()) { |
+ if (it->first.second == process_handle) |
+ surface_textures_.erase(it++); |
+ else |
+ ++it; |
+ } |
+ } |
+ |
+ jobject GetSurface(int surface_texture_id, |
+ base::ProcessHandle process_handle) const { |
+ base::AutoLock lock(surface_textures_lock_); |
+ SurfaceTextureMap::const_iterator it = surface_textures_.find( |
+ SurfaceTextureMapKey(surface_texture_id, process_handle)); |
+ return it == surface_textures_.end() |
+ ? NULL |
+ : it->second->surface.j_surface().obj(); |
+ } |
+ |
+ private: |
+ struct SurfaceTextureInfo { |
+ explicit SurfaceTextureInfo(gfx::SurfaceTexture* surface_texture) |
+ : surface_texture(surface_texture), surface(surface_texture) {} |
+ |
+ scoped_refptr<gfx::SurfaceTexture> surface_texture; |
+ gfx::ScopedJavaSurface surface; |
+ }; |
+ |
+ typedef std::pair<int, base::ProcessHandle> SurfaceTextureMapKey; |
+ typedef base::ScopedPtrHashMap<SurfaceTextureMapKey, SurfaceTextureInfo> |
+ SurfaceTextureMap; |
+ SurfaceTextureMap surface_textures_; |
+ mutable base::Lock surface_textures_lock_; |
+ base::ThreadChecker thread_checker_; |
+}; |
+base::LazyInstance<SurfaceTextureTrackerImpl> g_surface_texture_tracker = |
+ LAZY_INSTANCE_INITIALIZER; |
+ |
+} // namespace |
+ |
+#endif // OS_ANDROID |
+ |
GpuChannelManager::ImageOperation::ImageOperation( |
int32 sync_point, base::Closure callback) |
: sync_point(sync_point), |
@@ -45,6 +129,9 @@ GpuChannelManager::GpuChannelManager(MessageRouter* router, |
DCHECK(router_); |
DCHECK(io_message_loop); |
DCHECK(shutdown_event); |
+ // SurfaceTextureTracker instance must be set before we establish a channel |
+ // that could be using it to initialize GLImage instances. |
+ gfx::SurfaceTextureTracker::InitInstance(g_surface_texture_tracker.Pointer()); |
} |
GpuChannelManager::~GpuChannelManager() { |
@@ -104,6 +191,7 @@ bool GpuChannelManager::OnMessageReceived(const IPC::Message& msg) { |
IPC_MESSAGE_HANDLER(GpuMsg_CreateImage, OnCreateImage) |
IPC_MESSAGE_HANDLER(GpuMsg_DeleteImage, OnDeleteImage) |
IPC_MESSAGE_HANDLER(GpuMsg_LoadedShader, OnLoadedShader) |
+ IPC_MESSAGE_HANDLER(GpuMsg_CreateSurfaceTexture, OnCreateSurfaceTexture) |
IPC_MESSAGE_UNHANDLED(handled = false) |
IPC_END_MESSAGE_MAP_EX() |
return handled; |
@@ -264,6 +352,20 @@ bool GpuChannelManager::HandleMessagesScheduled() { |
return false; |
} |
+void GpuChannelManager::OnCreateSurfaceTexture( |
+ int32 surface_texture_id, int32 process_handle) { |
+ DCHECK(surface_texture_id); |
+#if defined(OS_ANDROID) |
+ const int kDummyTextureId = 0; |
+ scoped_refptr<gfx::SurfaceTexture> surface_texture = |
+ gfx::SurfaceTexture::Create(kDummyTextureId); |
+ g_surface_texture_tracker.Pointer()->AddSurfaceTexture( |
+ surface_texture.get(), |
+ surface_texture_id, |
+ static_cast<base::ProcessHandle>(process_handle)); |
+#endif // OS_ANDROID |
+} |
+ |
uint64 GpuChannelManager::MessagesProcessed() { |
uint64 messages_processed = 0; |