Chromium Code Reviews| Index: content/browser/renderer_host/compositor_impl_android.cc |
| diff --git a/content/browser/renderer_host/compositor_impl_android.cc b/content/browser/renderer_host/compositor_impl_android.cc |
| index 5f80889ca63ed2cccf7c68792bd6536b172fff3e..5427692d5ea970b3874e18cf14f67eb3737f2592 100644 |
| --- a/content/browser/renderer_host/compositor_impl_android.cc |
| +++ b/content/browser/renderer_host/compositor_impl_android.cc |
| @@ -12,11 +12,13 @@ |
| #include "base/android/scoped_java_ref.h" |
| #include "base/bind.h" |
| #include "base/command_line.h" |
| +#include "base/containers/scoped_ptr_hash_map.h" |
| #include "base/lazy_instance.h" |
| #include "base/logging.h" |
| #include "base/single_thread_task_runner.h" |
| #include "base/synchronization/lock.h" |
| #include "base/threading/thread.h" |
| +#include "base/threading/thread_checker.h" |
| #include "cc/base/switches.h" |
| #include "cc/input/input_handler.h" |
| #include "cc/layers/layer.h" |
| @@ -43,6 +45,9 @@ |
| #include "ui/gfx/android/device_display_info.h" |
| #include "ui/gfx/android/java_bitmap.h" |
| #include "ui/gfx/frame_time.h" |
| +#include "ui/gl/android/scoped_java_surface.h" |
| +#include "ui/gl/android/surface_texture.h" |
| +#include "ui/gl/android/surface_texture_tracker.h" |
| #include "webkit/common/gpu/context_provider_in_process.h" |
| #include "webkit/common/gpu/webgraphicscontext3d_in_process_command_buffer_impl.h" |
| @@ -131,6 +136,80 @@ class TransientUIResource : public cc::ScopedUIResource { |
| bool retrieved_; |
| }; |
| +class SurfaceTextureTrackerImpl : public gfx::SurfaceTextureTracker { |
| + public: |
| + SurfaceTextureTrackerImpl() : next_surface_texture_id_(1) { |
| + 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; |
| + } |
| + |
| + int AddSurfaceTexture(gfx::SurfaceTexture* surface_texture, |
| + base::ProcessHandle process_handle) { |
| + DCHECK(thread_checker_.CalledOnValidThread()); |
| + int surface_texture_id = next_surface_texture_id_++; |
| + if (next_surface_texture_id_ == INT_MAX) |
| + next_surface_texture_id_ = 1; |
| + |
| + 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))); |
| + return surface_texture_id; |
| + } |
| + |
| + 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(); |
|
piman
2014/03/27 01:07:25
Is the jobject returned thread safe? What if Remov
reveman
2014/03/27 14:48:11
Good call. We probably have to take a ref here and
no sievers
2014/03/27 18:25:25
There are a few things:
- The SurfaceTexture nati
|
| + } |
| + |
| + 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_; |
| + int next_surface_texture_id_; |
| + base::ThreadChecker thread_checker_; |
| +}; |
| +base::LazyInstance<SurfaceTextureTrackerImpl> g_surface_texture_tracker = |
| + LAZY_INSTANCE_INITIALIZER; |
| + |
| static bool g_initialized = false; |
| } // anonymous namespace |
| @@ -152,6 +231,9 @@ Compositor* Compositor::Create(CompositorClient* client, |
| // static |
| void Compositor::Initialize() { |
| DCHECK(!CompositorImpl::IsInitialized()); |
| + // SurfaceTextureTracker instance must be set before we create a GPU thread |
| + // that could be using it to initialize GLImage instances. |
| + gfx::SurfaceTextureTracker::InitInstance(g_surface_texture_tracker.Pointer()); |
| g_initialized = true; |
| } |
| @@ -171,6 +253,33 @@ jobject CompositorImpl::GetSurface(int surface_id) { |
| return jsurface; |
| } |
| +// static |
| +jobject CompositorImpl::GetSurfaceTextureSurface( |
| + int surface_texture_id, |
| + base::ProcessHandle process_handle) { |
| + jobject jsurface = g_surface_texture_tracker.Pointer()->GetSurface( |
| + surface_texture_id, process_handle); |
| + |
| + LOG_IF(WARNING, !jsurface) << "No surface for surface texture id " |
| + << surface_texture_id; |
| + return jsurface; |
| +} |
| + |
| +// static |
| +int CompositorImpl::AllocateSurfaceTexture(base::ProcessHandle process_handle) { |
| + const int kDummyTextureId = 0; |
| + scoped_refptr<gfx::SurfaceTexture> surface_texture = |
| + gfx::SurfaceTexture::Create(kDummyTextureId); |
| + return g_surface_texture_tracker.Pointer()->AddSurfaceTexture( |
| + surface_texture.get(), process_handle); |
| +} |
| + |
| +// static |
| +void CompositorImpl::DestroyAllSurfaceTextures( |
| + base::ProcessHandle process_handle) { |
| + g_surface_texture_tracker.Pointer()->RemoveAllSurfaceTextures(process_handle); |
| +} |
| + |
| CompositorImpl::CompositorImpl(CompositorClient* client, |
| gfx::NativeWindow root_window) |
| : root_layer_(cc::Layer::Create()), |