OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "android_webview/browser/hardware_renderer.h" | 5 #include "android_webview/browser/hardware_renderer.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "android_webview/browser/aw_gl_surface.h" | 9 #include "android_webview/browser/aw_gl_surface.h" |
10 #include "android_webview/browser/aw_render_thread_context_provider.h" | 10 #include "android_webview/browser/aw_render_thread_context_provider.h" |
(...skipping 20 matching lines...) Expand all Loading... |
31 #include "ui/gfx/geometry/rect_f.h" | 31 #include "ui/gfx/geometry/rect_f.h" |
32 #include "ui/gfx/transform.h" | 32 #include "ui/gfx/transform.h" |
33 #include "ui/gl/gl_bindings.h" | 33 #include "ui/gl/gl_bindings.h" |
34 | 34 |
35 namespace android_webview { | 35 namespace android_webview { |
36 | 36 |
37 HardwareRenderer::HardwareRenderer(SharedRendererState* state) | 37 HardwareRenderer::HardwareRenderer(SharedRendererState* state) |
38 : shared_renderer_state_(state), | 38 : shared_renderer_state_(state), |
39 last_egl_context_(eglGetCurrentContext()), | 39 last_egl_context_(eglGetCurrentContext()), |
40 gl_surface_(new AwGLSurface), | 40 gl_surface_(new AwGLSurface), |
41 compositor_id_(0), // Valid compositor id starts at 1. | 41 compositor_id_(0u), // Valid compositor id starts at 1. |
| 42 last_committed_output_surface_id_(0u), |
| 43 last_submitted_output_surface_id_(0u), |
42 output_surface_(NULL) { | 44 output_surface_(NULL) { |
43 DCHECK(last_egl_context_); | 45 DCHECK(last_egl_context_); |
44 | 46 |
45 cc::RendererSettings settings; | 47 cc::RendererSettings settings; |
46 | 48 |
47 // Should be kept in sync with compositor_impl_android.cc. | 49 // Should be kept in sync with compositor_impl_android.cc. |
48 settings.allow_antialiasing = false; | 50 settings.allow_antialiasing = false; |
49 settings.highp_threshold_min = 2048; | 51 settings.highp_threshold_min = 2048; |
50 | 52 |
51 // Webview does not own the surface so should not clear it. | 53 // Webview does not own the surface so should not clear it. |
(...skipping 27 matching lines...) Expand all Loading... |
79 } | 81 } |
80 | 82 |
81 void HardwareRenderer::CommitFrame() { | 83 void HardwareRenderer::CommitFrame() { |
82 TRACE_EVENT0("android_webview", "CommitFrame"); | 84 TRACE_EVENT0("android_webview", "CommitFrame"); |
83 scroll_offset_ = shared_renderer_state_->GetScrollOffsetOnRT(); | 85 scroll_offset_ = shared_renderer_state_->GetScrollOffsetOnRT(); |
84 scoped_ptr<ChildFrame> child_frame = | 86 scoped_ptr<ChildFrame> child_frame = |
85 shared_renderer_state_->PassCompositorFrameOnRT(); | 87 shared_renderer_state_->PassCompositorFrameOnRT(); |
86 if (!child_frame.get()) | 88 if (!child_frame.get()) |
87 return; | 89 return; |
88 | 90 |
| 91 last_committed_output_surface_id_ = child_frame->output_surface_id; |
89 ReturnResourcesInChildFrame(); | 92 ReturnResourcesInChildFrame(); |
90 child_frame_ = std::move(child_frame); | 93 child_frame_ = std::move(child_frame); |
91 DCHECK(child_frame_->frame.get()); | 94 DCHECK(child_frame_->frame.get()); |
92 DCHECK(!child_frame_->frame->gl_frame_data); | 95 DCHECK(!child_frame_->frame->gl_frame_data); |
93 } | 96 } |
94 | 97 |
95 void HardwareRenderer::DrawGL(AwDrawGLInfo* draw_info, | 98 void HardwareRenderer::DrawGL(AwDrawGLInfo* draw_info, |
96 const ScopedAppGLStateRestore& gl_state) { | 99 const ScopedAppGLStateRestore& gl_state) { |
97 TRACE_EVENT0("android_webview", "HardwareRenderer::DrawGL"); | 100 TRACE_EVENT0("android_webview", "HardwareRenderer::DrawGL"); |
98 | 101 |
99 // We need to watch if the current Android context has changed and enforce | 102 // We need to watch if the current Android context has changed and enforce |
100 // a clean-up in the compositor. | 103 // a clean-up in the compositor. |
101 EGLContext current_context = eglGetCurrentContext(); | 104 EGLContext current_context = eglGetCurrentContext(); |
102 DCHECK(current_context) << "DrawGL called without EGLContext"; | 105 DCHECK(current_context) << "DrawGL called without EGLContext"; |
103 | 106 |
104 // TODO(boliu): Handle context loss. | 107 // TODO(boliu): Handle context loss. |
105 if (last_egl_context_ != current_context) | 108 if (last_egl_context_ != current_context) |
106 DLOG(WARNING) << "EGLContextChanged"; | 109 DLOG(WARNING) << "EGLContextChanged"; |
107 | 110 |
108 // SurfaceFactory::SubmitCompositorFrame might call glFlush. So calling it | 111 // SurfaceFactory::SubmitCompositorFrame might call glFlush. So calling it |
109 // during "kModeSync" stage (which does not allow GL) might result in extra | 112 // during "kModeSync" stage (which does not allow GL) might result in extra |
110 // kModeProcess. Instead, submit the frame in "kModeDraw" stage to avoid | 113 // kModeProcess. Instead, submit the frame in "kModeDraw" stage to avoid |
111 // unnecessary kModeProcess. | 114 // unnecessary kModeProcess. |
112 if (child_frame_.get() && child_frame_->frame.get()) { | 115 if (child_frame_.get() && child_frame_->frame.get()) { |
113 if (compositor_id_ != child_frame_->compositor_id) { | 116 if (compositor_id_ != child_frame_->compositor_id || |
| 117 last_submitted_output_surface_id_ != child_frame_->output_surface_id) { |
114 if (!root_id_.is_null()) | 118 if (!root_id_.is_null()) |
115 surface_factory_->Destroy(root_id_); | 119 surface_factory_->Destroy(root_id_); |
116 if (!child_id_.is_null()) | 120 if (!child_id_.is_null()) |
117 surface_factory_->Destroy(child_id_); | 121 surface_factory_->Destroy(child_id_); |
118 | 122 |
119 root_id_ = cc::SurfaceId(); | 123 root_id_ = cc::SurfaceId(); |
120 child_id_ = cc::SurfaceId(); | 124 child_id_ = cc::SurfaceId(); |
121 | 125 |
122 // This will return all the resources to the previous compositor. | 126 // This will return all the resources to the previous compositor. |
123 surface_factory_.reset(); | 127 surface_factory_.reset(); |
124 compositor_id_ = child_frame_->compositor_id; | 128 compositor_id_ = child_frame_->compositor_id; |
| 129 last_submitted_output_surface_id_ = child_frame_->output_surface_id; |
125 surface_factory_.reset( | 130 surface_factory_.reset( |
126 new cc::SurfaceFactory(surface_manager_.get(), this)); | 131 new cc::SurfaceFactory(surface_manager_.get(), this)); |
127 } | 132 } |
128 | 133 |
129 scoped_ptr<cc::CompositorFrame> child_compositor_frame = | 134 scoped_ptr<cc::CompositorFrame> child_compositor_frame = |
130 std::move(child_frame_->frame); | 135 std::move(child_frame_->frame); |
131 | 136 |
132 // On Android we put our browser layers in physical pixels and set our | 137 // On Android we put our browser layers in physical pixels and set our |
133 // browser CC device_scale_factor to 1, so suppress the transform between | 138 // browser CC device_scale_factor to 1, so suppress the transform between |
134 // DIP and pixels. | 139 // DIP and pixels. |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
216 output_surface_ = output_surface_holder.get(); | 221 output_surface_ = output_surface_holder.get(); |
217 display_->Initialize(std::move(output_surface_holder), nullptr); | 222 display_->Initialize(std::move(output_surface_holder), nullptr); |
218 } | 223 } |
219 output_surface_->SetGLState(gl_state); | 224 output_surface_->SetGLState(gl_state); |
220 display_->SetExternalClip(clip); | 225 display_->SetExternalClip(clip); |
221 display_->DrawAndSwap(); | 226 display_->DrawAndSwap(); |
222 } | 227 } |
223 | 228 |
224 void HardwareRenderer::ReturnResources( | 229 void HardwareRenderer::ReturnResources( |
225 const cc::ReturnedResourceArray& resources) { | 230 const cc::ReturnedResourceArray& resources) { |
226 ReturnResourcesToCompositor(resources, compositor_id_); | 231 ReturnResourcesToCompositor(resources, compositor_id_, |
| 232 last_submitted_output_surface_id_); |
227 } | 233 } |
228 | 234 |
229 void HardwareRenderer::SetBeginFrameSource( | 235 void HardwareRenderer::SetBeginFrameSource( |
230 cc::BeginFrameSource* begin_frame_source) { | 236 cc::BeginFrameSource* begin_frame_source) { |
231 // TODO(tansell): Hook this up. | 237 // TODO(tansell): Hook this up. |
232 } | 238 } |
233 | 239 |
234 void HardwareRenderer::SetBackingFrameBufferObject( | 240 void HardwareRenderer::SetBackingFrameBufferObject( |
235 int framebuffer_binding_ext) { | 241 int framebuffer_binding_ext) { |
236 gl_surface_->SetBackingFrameBufferObject(framebuffer_binding_ext); | 242 gl_surface_->SetBackingFrameBufferObject(framebuffer_binding_ext); |
237 } | 243 } |
238 | 244 |
239 void HardwareRenderer::ReturnResourcesInChildFrame() { | 245 void HardwareRenderer::ReturnResourcesInChildFrame() { |
240 if (child_frame_.get() && child_frame_->frame.get()) { | 246 if (child_frame_.get() && child_frame_->frame.get()) { |
241 cc::ReturnedResourceArray resources_to_return; | 247 cc::ReturnedResourceArray resources_to_return; |
242 cc::TransferableResource::ReturnResources( | 248 cc::TransferableResource::ReturnResources( |
243 child_frame_->frame->delegated_frame_data->resource_list, | 249 child_frame_->frame->delegated_frame_data->resource_list, |
244 &resources_to_return); | 250 &resources_to_return); |
245 | 251 |
246 // The child frame's compositor id is not necessarily same as | 252 // The child frame's compositor id is not necessarily same as |
247 // compositor_id_. | 253 // compositor_id_. |
248 ReturnResourcesToCompositor(resources_to_return, | 254 ReturnResourcesToCompositor(resources_to_return, |
249 child_frame_->compositor_id); | 255 child_frame_->compositor_id, |
| 256 child_frame_->output_surface_id); |
250 } | 257 } |
251 child_frame_.reset(); | 258 child_frame_.reset(); |
252 } | 259 } |
253 | 260 |
254 void HardwareRenderer::ReturnResourcesToCompositor( | 261 void HardwareRenderer::ReturnResourcesToCompositor( |
255 const cc::ReturnedResourceArray& resources, | 262 const cc::ReturnedResourceArray& resources, |
256 uint32_t compositor_id) { | 263 uint32_t compositor_id, |
257 shared_renderer_state_->InsertReturnedResourcesOnRT(resources, compositor_id); | 264 uint32_t output_surface_id) { |
| 265 if (output_surface_id != last_committed_output_surface_id_) |
| 266 return; |
| 267 shared_renderer_state_->InsertReturnedResourcesOnRT(resources, compositor_id, |
| 268 output_surface_id); |
258 } | 269 } |
259 | 270 |
260 } // namespace android_webview | 271 } // namespace android_webview |
OLD | NEW |