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