| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/browser/renderer_host/compositor_impl_android.h" | 5 #include "content/browser/renderer_host/compositor_impl_android.h" |
| 6 | 6 |
| 7 #include <android/bitmap.h> | 7 #include <android/bitmap.h> |
| 8 #include <android/native_window_jni.h> | 8 #include <android/native_window_jni.h> |
| 9 | 9 |
| 10 #include "base/android/jni_android.h" | 10 #include "base/android/jni_android.h" |
| 11 #include "base/android/scoped_java_ref.h" | 11 #include "base/android/scoped_java_ref.h" |
| 12 #include "base/bind.h" | 12 #include "base/bind.h" |
| 13 #include "base/cancelable_callback.h" |
| 13 #include "base/command_line.h" | 14 #include "base/command_line.h" |
| 14 #include "base/containers/hash_tables.h" | 15 #include "base/containers/hash_tables.h" |
| 15 #include "base/lazy_instance.h" | 16 #include "base/lazy_instance.h" |
| 16 #include "base/logging.h" | 17 #include "base/logging.h" |
| 17 #include "base/memory/weak_ptr.h" | 18 #include "base/memory/weak_ptr.h" |
| 18 #include "base/single_thread_task_runner.h" | 19 #include "base/single_thread_task_runner.h" |
| 19 #include "base/synchronization/lock.h" | 20 #include "base/synchronization/lock.h" |
| 20 #include "base/threading/thread.h" | 21 #include "base/threading/thread.h" |
| 21 #include "base/threading/thread_checker.h" | 22 #include "base/threading/thread_checker.h" |
| 22 #include "cc/base/switches.h" | 23 #include "cc/base/switches.h" |
| 23 #include "cc/input/input_handler.h" | 24 #include "cc/input/input_handler.h" |
| 24 #include "cc/layers/layer.h" | 25 #include "cc/layers/layer.h" |
| 25 #include "cc/output/compositor_frame.h" | 26 #include "cc/output/compositor_frame.h" |
| 26 #include "cc/output/context_provider.h" | 27 #include "cc/output/context_provider.h" |
| 27 #include "cc/output/output_surface.h" | 28 #include "cc/output/output_surface.h" |
| 28 #include "cc/trees/layer_tree_host.h" | 29 #include "cc/trees/layer_tree_host.h" |
| 29 #include "content/browser/android/child_process_launcher_android.h" | 30 #include "content/browser/android/child_process_launcher_android.h" |
| 30 #include "content/browser/gpu/browser_gpu_channel_host_factory.h" | 31 #include "content/browser/gpu/browser_gpu_channel_host_factory.h" |
| 31 #include "content/browser/gpu/gpu_surface_tracker.h" | 32 #include "content/browser/gpu/gpu_surface_tracker.h" |
| 33 #include "content/browser/renderer_host/render_widget_host_impl.h" |
| 32 #include "content/common/gpu/client/command_buffer_proxy_impl.h" | 34 #include "content/common/gpu/client/command_buffer_proxy_impl.h" |
| 33 #include "content/common/gpu/client/context_provider_command_buffer.h" | 35 #include "content/common/gpu/client/context_provider_command_buffer.h" |
| 34 #include "content/common/gpu/client/gl_helper.h" | 36 #include "content/common/gpu/client/gl_helper.h" |
| 35 #include "content/common/gpu/client/gpu_channel_host.h" | 37 #include "content/common/gpu/client/gpu_channel_host.h" |
| 36 #include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h" | 38 #include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h" |
| 37 #include "content/common/gpu/gpu_process_launch_causes.h" | 39 #include "content/common/gpu/gpu_process_launch_causes.h" |
| 38 #include "content/common/host_shared_bitmap_manager.h" | 40 #include "content/common/host_shared_bitmap_manager.h" |
| 39 #include "content/public/browser/android/compositor_client.h" | 41 #include "content/public/browser/android/compositor_client.h" |
| 42 #include "gpu/command_buffer/client/context_support.h" |
| 40 #include "gpu/command_buffer/client/gles2_interface.h" | 43 #include "gpu/command_buffer/client/gles2_interface.h" |
| 41 #include "third_party/khronos/GLES2/gl2.h" | 44 #include "third_party/khronos/GLES2/gl2.h" |
| 42 #include "third_party/khronos/GLES2/gl2ext.h" | 45 #include "third_party/khronos/GLES2/gl2ext.h" |
| 43 #include "third_party/skia/include/core/SkMallocPixelRef.h" | 46 #include "third_party/skia/include/core/SkMallocPixelRef.h" |
| 44 #include "ui/base/android/window_android.h" | 47 #include "ui/base/android/window_android.h" |
| 45 #include "ui/gfx/android/device_display_info.h" | 48 #include "ui/gfx/android/device_display_info.h" |
| 46 #include "ui/gfx/frame_time.h" | 49 #include "ui/gfx/frame_time.h" |
| 47 #include "ui/gl/android/surface_texture.h" | 50 #include "ui/gl/android/surface_texture.h" |
| 48 #include "ui/gl/android/surface_texture_tracker.h" | 51 #include "ui/gl/android/surface_texture_tracker.h" |
| 49 #include "webkit/common/gpu/context_provider_in_process.h" | 52 #include "webkit/common/gpu/context_provider_in_process.h" |
| 50 #include "webkit/common/gpu/webgraphicscontext3d_in_process_command_buffer_impl.
h" | 53 #include "webkit/common/gpu/webgraphicscontext3d_in_process_command_buffer_impl.
h" |
| 51 | 54 |
| 55 namespace content { |
| 56 |
| 52 namespace { | 57 namespace { |
| 53 | 58 |
| 54 const unsigned int kMaxSwapBuffers = 2U; | 59 const unsigned int kMaxSwapBuffers = 2U; |
| 55 | 60 |
| 56 // Used to override capabilities_.adjust_deadline_for_parent to false | 61 // Used to override capabilities_.adjust_deadline_for_parent to false |
| 57 class OutputSurfaceWithoutParent : public cc::OutputSurface { | 62 class OutputSurfaceWithoutParent : public cc::OutputSurface { |
| 58 public: | 63 public: |
| 59 OutputSurfaceWithoutParent(const scoped_refptr< | 64 OutputSurfaceWithoutParent( |
| 60 content::ContextProviderCommandBuffer>& context_provider, | 65 const scoped_refptr<ContextProviderCommandBuffer>& context_provider, |
| 61 base::WeakPtr<content::CompositorImpl> compositor_impl) | 66 base::WeakPtr<CompositorImpl> compositor_impl) |
| 62 : cc::OutputSurface(context_provider) { | 67 : cc::OutputSurface(context_provider), |
| 68 swap_buffers_completion_callback_( |
| 69 base::Bind(&OutputSurfaceWithoutParent::OnSwapBuffersCompleted, |
| 70 base::Unretained(this))) { |
| 63 capabilities_.adjust_deadline_for_parent = false; | 71 capabilities_.adjust_deadline_for_parent = false; |
| 64 compositor_impl_ = compositor_impl; | 72 compositor_impl_ = compositor_impl; |
| 65 main_thread_ = base::MessageLoopProxy::current(); | 73 main_thread_ = base::MessageLoopProxy::current(); |
| 66 } | 74 } |
| 67 | 75 |
| 68 virtual void SwapBuffers(cc::CompositorFrame* frame) override { | 76 virtual void SwapBuffers(cc::CompositorFrame* frame) override { |
| 69 for (size_t i = 0; i < frame->metadata.latency_info.size(); i++) { | 77 for (size_t i = 0; i < frame->metadata.latency_info.size(); i++) { |
| 70 frame->metadata.latency_info[i].AddLatencyNumber( | 78 frame->metadata.latency_info[i].AddLatencyNumber( |
| 71 ui::INPUT_EVENT_BROWSER_SWAP_BUFFER_COMPONENT, 0, 0); | 79 ui::INPUT_EVENT_BROWSER_SWAP_BUFFER_COMPONENT, 0, 0); |
| 72 } | 80 } |
| 73 | 81 |
| 74 content::ContextProviderCommandBuffer* provider_command_buffer = | 82 GetCommandBufferProxy()->SetLatencyInfo(frame->metadata.latency_info); |
| 75 static_cast<content::ContextProviderCommandBuffer*>( | 83 DCHECK(frame->gl_frame_data->sub_buffer_rect == |
| 76 context_provider_.get()); | 84 gfx::Rect(frame->gl_frame_data->size)); |
| 77 content::CommandBufferProxyImpl* command_buffer_proxy = | 85 context_provider_->ContextSupport()->Swap(); |
| 78 provider_command_buffer->GetCommandBufferProxy(); | |
| 79 DCHECK(command_buffer_proxy); | |
| 80 command_buffer_proxy->SetLatencyInfo(frame->metadata.latency_info); | |
| 81 | |
| 82 OutputSurface::SwapBuffers(frame); | |
| 83 } | 86 } |
| 84 | 87 |
| 85 virtual bool BindToClient(cc::OutputSurfaceClient* client) override { | 88 virtual bool BindToClient(cc::OutputSurfaceClient* client) override { |
| 86 if (!OutputSurface::BindToClient(client)) | 89 if (!OutputSurface::BindToClient(client)) |
| 87 return false; | 90 return false; |
| 88 | 91 |
| 92 GetCommandBufferProxy()->SetSwapBuffersCompletionCallback( |
| 93 swap_buffers_completion_callback_.callback()); |
| 94 |
| 89 main_thread_->PostTask( | 95 main_thread_->PostTask( |
| 90 FROM_HERE, | 96 FROM_HERE, |
| 91 base::Bind(&content::CompositorImpl::PopulateGpuCapabilities, | 97 base::Bind(&CompositorImpl::PopulateGpuCapabilities, |
| 92 compositor_impl_, | 98 compositor_impl_, |
| 93 context_provider_->ContextCapabilities().gpu)); | 99 context_provider_->ContextCapabilities().gpu)); |
| 94 | 100 |
| 95 return true; | 101 return true; |
| 96 } | 102 } |
| 97 | 103 |
| 104 private: |
| 105 CommandBufferProxyImpl* GetCommandBufferProxy() { |
| 106 ContextProviderCommandBuffer* provider_command_buffer = |
| 107 static_cast<content::ContextProviderCommandBuffer*>( |
| 108 context_provider_.get()); |
| 109 CommandBufferProxyImpl* command_buffer_proxy = |
| 110 provider_command_buffer->GetCommandBufferProxy(); |
| 111 DCHECK(command_buffer_proxy); |
| 112 return command_buffer_proxy; |
| 113 } |
| 114 |
| 115 void OnSwapBuffersCompleted( |
| 116 const std::vector<ui::LatencyInfo>& latency_info) { |
| 117 RenderWidgetHostImpl::CompositorFrameDrawn(latency_info); |
| 118 OutputSurface::OnSwapBuffersComplete(); |
| 119 } |
| 120 |
| 121 base::CancelableCallback<void(const std::vector<ui::LatencyInfo>&)> |
| 122 swap_buffers_completion_callback_; |
| 123 |
| 98 scoped_refptr<base::MessageLoopProxy> main_thread_; | 124 scoped_refptr<base::MessageLoopProxy> main_thread_; |
| 99 base::WeakPtr<content::CompositorImpl> compositor_impl_; | 125 base::WeakPtr<CompositorImpl> compositor_impl_; |
| 100 }; | 126 }; |
| 101 | 127 |
| 102 class SurfaceTextureTrackerImpl : public gfx::SurfaceTextureTracker { | 128 class SurfaceTextureTrackerImpl : public gfx::SurfaceTextureTracker { |
| 103 public: | 129 public: |
| 104 SurfaceTextureTrackerImpl() : next_surface_texture_id_(1) { | 130 SurfaceTextureTrackerImpl() : next_surface_texture_id_(1) { |
| 105 thread_checker_.DetachFromThread(); | 131 thread_checker_.DetachFromThread(); |
| 106 } | 132 } |
| 107 | 133 |
| 108 // Overridden from gfx::SurfaceTextureTracker: | 134 // Overridden from gfx::SurfaceTextureTracker: |
| 109 virtual scoped_refptr<gfx::SurfaceTexture> AcquireSurfaceTexture( | 135 virtual scoped_refptr<gfx::SurfaceTexture> AcquireSurfaceTexture( |
| (...skipping 13 matching lines...) Expand all Loading... |
| 123 int child_process_id) { | 149 int child_process_id) { |
| 124 DCHECK(thread_checker_.CalledOnValidThread()); | 150 DCHECK(thread_checker_.CalledOnValidThread()); |
| 125 int surface_texture_id = next_surface_texture_id_++; | 151 int surface_texture_id = next_surface_texture_id_++; |
| 126 if (next_surface_texture_id_ == INT_MAX) | 152 if (next_surface_texture_id_ == INT_MAX) |
| 127 next_surface_texture_id_ = 1; | 153 next_surface_texture_id_ = 1; |
| 128 | 154 |
| 129 base::AutoLock lock(surface_textures_lock_); | 155 base::AutoLock lock(surface_textures_lock_); |
| 130 SurfaceTextureMapKey key(surface_texture_id, child_process_id); | 156 SurfaceTextureMapKey key(surface_texture_id, child_process_id); |
| 131 DCHECK(surface_textures_.find(key) == surface_textures_.end()); | 157 DCHECK(surface_textures_.find(key) == surface_textures_.end()); |
| 132 surface_textures_[key] = surface_texture; | 158 surface_textures_[key] = surface_texture; |
| 133 content::RegisterChildProcessSurfaceTexture( | 159 RegisterChildProcessSurfaceTexture( |
| 134 surface_texture_id, | 160 surface_texture_id, |
| 135 child_process_id, | 161 child_process_id, |
| 136 surface_texture->j_surface_texture().obj()); | 162 surface_texture->j_surface_texture().obj()); |
| 137 return surface_texture_id; | 163 return surface_texture_id; |
| 138 } | 164 } |
| 139 | 165 |
| 140 void RemoveAllSurfaceTextures(int child_process_id) { | 166 void RemoveAllSurfaceTextures(int child_process_id) { |
| 141 DCHECK(thread_checker_.CalledOnValidThread()); | 167 DCHECK(thread_checker_.CalledOnValidThread()); |
| 142 base::AutoLock lock(surface_textures_lock_); | 168 base::AutoLock lock(surface_textures_lock_); |
| 143 SurfaceTextureMap::iterator it = surface_textures_.begin(); | 169 SurfaceTextureMap::iterator it = surface_textures_.begin(); |
| 144 while (it != surface_textures_.end()) { | 170 while (it != surface_textures_.end()) { |
| 145 if (it->first.second == child_process_id) { | 171 if (it->first.second == child_process_id) { |
| 146 content::UnregisterChildProcessSurfaceTexture(it->first.first, | 172 UnregisterChildProcessSurfaceTexture(it->first.first, it->first.second); |
| 147 it->first.second); | |
| 148 surface_textures_.erase(it++); | 173 surface_textures_.erase(it++); |
| 149 } else { | 174 } else { |
| 150 ++it; | 175 ++it; |
| 151 } | 176 } |
| 152 } | 177 } |
| 153 } | 178 } |
| 154 | 179 |
| 155 private: | 180 private: |
| 156 typedef std::pair<int, int> SurfaceTextureMapKey; | 181 typedef std::pair<int, int> SurfaceTextureMapKey; |
| 157 typedef base::hash_map<SurfaceTextureMapKey, | 182 typedef base::hash_map<SurfaceTextureMapKey, |
| 158 scoped_refptr<gfx::SurfaceTexture> > | 183 scoped_refptr<gfx::SurfaceTexture> > |
| 159 SurfaceTextureMap; | 184 SurfaceTextureMap; |
| 160 SurfaceTextureMap surface_textures_; | 185 SurfaceTextureMap surface_textures_; |
| 161 mutable base::Lock surface_textures_lock_; | 186 mutable base::Lock surface_textures_lock_; |
| 162 int next_surface_texture_id_; | 187 int next_surface_texture_id_; |
| 163 base::ThreadChecker thread_checker_; | 188 base::ThreadChecker thread_checker_; |
| 164 }; | 189 }; |
| 165 base::LazyInstance<SurfaceTextureTrackerImpl> g_surface_texture_tracker = | 190 base::LazyInstance<SurfaceTextureTrackerImpl> g_surface_texture_tracker = |
| 166 LAZY_INSTANCE_INITIALIZER; | 191 LAZY_INSTANCE_INITIALIZER; |
| 167 | 192 |
| 168 static bool g_initialized = false; | 193 static bool g_initialized = false; |
| 169 | 194 |
| 170 } // anonymous namespace | 195 } // anonymous namespace |
| 171 | 196 |
| 172 namespace content { | |
| 173 | |
| 174 // static | 197 // static |
| 175 Compositor* Compositor::Create(CompositorClient* client, | 198 Compositor* Compositor::Create(CompositorClient* client, |
| 176 gfx::NativeWindow root_window) { | 199 gfx::NativeWindow root_window) { |
| 177 return client ? new CompositorImpl(client, root_window) : NULL; | 200 return client ? new CompositorImpl(client, root_window) : NULL; |
| 178 } | 201 } |
| 179 | 202 |
| 180 // static | 203 // static |
| 181 void Compositor::Initialize() { | 204 void Compositor::Initialize() { |
| 182 DCHECK(!CompositorImpl::IsInitialized()); | 205 DCHECK(!CompositorImpl::IsInitialized()); |
| 183 // SurfaceTextureTracker instance must be set before we create a GPU thread | 206 // SurfaceTextureTracker instance must be set before we create a GPU thread |
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 395 SetVisible(true); | 418 SetVisible(true); |
| 396 } | 419 } |
| 397 } | 420 } |
| 398 | 421 |
| 399 void CompositorImpl::SetSurface(jobject surface) { | 422 void CompositorImpl::SetSurface(jobject surface) { |
| 400 JNIEnv* env = base::android::AttachCurrentThread(); | 423 JNIEnv* env = base::android::AttachCurrentThread(); |
| 401 base::android::ScopedJavaLocalRef<jobject> j_surface(env, surface); | 424 base::android::ScopedJavaLocalRef<jobject> j_surface(env, surface); |
| 402 | 425 |
| 403 // First, cleanup any existing surface references. | 426 // First, cleanup any existing surface references. |
| 404 if (surface_id_) | 427 if (surface_id_) |
| 405 content::UnregisterViewSurface(surface_id_); | 428 UnregisterViewSurface(surface_id_); |
| 406 SetWindowSurface(NULL); | 429 SetWindowSurface(NULL); |
| 407 | 430 |
| 408 // Now, set the new surface if we have one. | 431 // Now, set the new surface if we have one. |
| 409 ANativeWindow* window = NULL; | 432 ANativeWindow* window = NULL; |
| 410 if (surface) { | 433 if (surface) { |
| 411 // Note: This ensures that any local references used by | 434 // Note: This ensures that any local references used by |
| 412 // ANativeWindow_fromSurface are released immediately. This is needed as a | 435 // ANativeWindow_fromSurface are released immediately. This is needed as a |
| 413 // workaround for https://code.google.com/p/android/issues/detail?id=68174 | 436 // workaround for https://code.google.com/p/android/issues/detail?id=68174 |
| 414 base::android::ScopedJavaLocalFrame scoped_local_reference_frame(env); | 437 base::android::ScopedJavaLocalFrame scoped_local_reference_frame(env); |
| 415 window = ANativeWindow_fromSurface(env, surface); | 438 window = ANativeWindow_fromSurface(env, surface); |
| 416 } | 439 } |
| 417 if (window) { | 440 if (window) { |
| 418 SetWindowSurface(window); | 441 SetWindowSurface(window); |
| 419 ANativeWindow_release(window); | 442 ANativeWindow_release(window); |
| 420 content::RegisterViewSurface(surface_id_, j_surface.obj()); | 443 RegisterViewSurface(surface_id_, j_surface.obj()); |
| 421 } | 444 } |
| 422 } | 445 } |
| 423 | 446 |
| 424 void CompositorImpl::SetVisible(bool visible) { | 447 void CompositorImpl::SetVisible(bool visible) { |
| 425 if (!visible) { | 448 if (!visible) { |
| 426 DCHECK(host_); | 449 DCHECK(host_); |
| 427 // Look for any layers that were attached to the root for readback | 450 // Look for any layers that were attached to the root for readback |
| 428 // and are waiting for Composite() to happen. | 451 // and are waiting for Composite() to happen. |
| 429 bool readback_pending = false; | 452 bool readback_pending = false; |
| 430 for (size_t i = 0; i < root_layer_->children().size(); ++i) { | 453 for (size_t i = 0; i < root_layer_->children().size(); ++i) { |
| (...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 687 } | 710 } |
| 688 | 711 |
| 689 void CompositorImpl::SetNeedsAnimate() { | 712 void CompositorImpl::SetNeedsAnimate() { |
| 690 if (!host_) | 713 if (!host_) |
| 691 return; | 714 return; |
| 692 | 715 |
| 693 host_->SetNeedsAnimate(); | 716 host_->SetNeedsAnimate(); |
| 694 } | 717 } |
| 695 | 718 |
| 696 } // namespace content | 719 } // namespace content |
| OLD | NEW |