Returning scoped_ptr instead of raw pointer in SpdySessionPoolInfoToValue() in net/
[chromium-blink-merge.git] / android_webview / browser / hardware_renderer.cc
blobd9760d2b7b5f076a3a719b8021418827ca61e03c
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
3 // found in the LICENSE file.
5 #include "android_webview/browser/hardware_renderer.h"
7 #include "android_webview/browser/aw_gl_surface.h"
8 #include "android_webview/browser/aw_render_thread_context_provider.h"
9 #include "android_webview/browser/child_frame.h"
10 #include "android_webview/browser/deferred_gpu_command_service.h"
11 #include "android_webview/browser/parent_compositor_draw_constraints.h"
12 #include "android_webview/browser/parent_output_surface.h"
13 #include "android_webview/browser/shared_renderer_state.h"
14 #include "android_webview/public/browser/draw_gl.h"
15 #include "base/auto_reset.h"
16 #include "base/strings/string_number_conversions.h"
17 #include "base/trace_event/trace_event.h"
18 #include "cc/layers/delegated_frame_provider.h"
19 #include "cc/layers/delegated_renderer_layer.h"
20 #include "cc/layers/layer.h"
21 #include "cc/output/compositor_frame.h"
22 #include "cc/output/output_surface.h"
23 #include "cc/scheduler/begin_frame_source.h"
24 #include "cc/trees/layer_tree_host.h"
25 #include "cc/trees/layer_tree_settings.h"
26 #include "gpu/command_buffer/client/gl_in_process_context.h"
27 #include "gpu/command_buffer/common/gles2_cmd_utils.h"
28 #include "ui/gfx/geometry/rect_conversions.h"
29 #include "ui/gfx/geometry/rect_f.h"
30 #include "ui/gfx/transform.h"
31 #include "ui/gl/gl_bindings.h"
33 namespace {
34 cc::LayerSettings HardwareRendererLayerSettings() {
35 return cc::LayerSettings();
39 namespace android_webview {
41 HardwareRenderer::HardwareRenderer(SharedRendererState* state)
42 : shared_renderer_state_(state),
43 last_egl_context_(eglGetCurrentContext()),
44 stencil_enabled_(false),
45 viewport_clip_valid_for_dcheck_(false),
46 gl_surface_(new AwGLSurface),
47 root_layer_(cc::Layer::Create(HardwareRendererLayerSettings())),
48 resource_collection_(new cc::DelegatedFrameResourceCollection),
49 output_surface_(NULL) {
50 DCHECK(last_egl_context_);
52 resource_collection_->SetClient(this);
54 cc::LayerTreeSettings settings;
56 // Should be kept in sync with compositor_impl_android.cc.
57 settings.renderer_settings.allow_antialiasing = false;
58 settings.renderer_settings.highp_threshold_min = 2048;
60 // Webview does not own the surface so should not clear it.
61 settings.renderer_settings.should_clear_root_render_pass = false;
63 // TODO(enne): Update this this compositor to use a synchronous scheduler.
64 settings.single_thread_proxy_scheduler = false;
66 cc::LayerTreeHost::InitParams params;
67 params.client = this;
68 params.settings = &settings;
69 layer_tree_host_ = cc::LayerTreeHost::CreateSingleThreaded(this, &params);
70 layer_tree_host_->SetRootLayer(root_layer_);
71 layer_tree_host_->SetLayerTreeHostClientReady();
72 layer_tree_host_->set_has_transparent_background(true);
75 HardwareRenderer::~HardwareRenderer() {
76 // Must reset everything before |resource_collection_| to ensure all
77 // resources are returned before resetting |resource_collection_| client.
78 layer_tree_host_.reset();
79 root_layer_ = NULL;
80 delegated_layer_ = NULL;
81 frame_provider_ = NULL;
82 #if DCHECK_IS_ON()
83 // Check collection is empty.
84 cc::ReturnedResourceArray returned_resources;
85 resource_collection_->TakeUnusedResourcesForChildCompositor(
86 &returned_resources);
87 DCHECK_EQ(0u, returned_resources.size());
88 #endif // DCHECK_IS_ON()
90 resource_collection_->SetClient(NULL);
92 // Reset draw constraints.
93 shared_renderer_state_->PostExternalDrawConstraintsToChildCompositorOnRT(
94 ParentCompositorDrawConstraints());
97 void HardwareRenderer::DidBeginMainFrame() {
98 // This is called after OutputSurface is created, but before the impl frame
99 // starts. We set the draw constraints here.
100 DCHECK(output_surface_);
101 DCHECK(viewport_clip_valid_for_dcheck_);
102 output_surface_->SetExternalStencilTest(stencil_enabled_);
103 output_surface_->SetDrawConstraints(viewport_, clip_);
106 void HardwareRenderer::CommitFrame() {
107 TRACE_EVENT0("android_webview", "CommitFrame");
108 scroll_offset_ = shared_renderer_state_->GetScrollOffsetOnRT();
110 scoped_ptr<ChildFrame> child_frame =
111 shared_renderer_state_->PassCompositorFrameOnRT();
112 if (!child_frame.get())
113 return;
114 child_frame_ = child_frame.Pass();
117 scoped_ptr<cc::CompositorFrame> frame = child_frame_->frame.Pass();
118 DCHECK(frame.get());
119 DCHECK(!frame->gl_frame_data);
120 DCHECK(!frame->software_frame_data);
122 // DelegatedRendererLayerImpl applies the inverse device_scale_factor of the
123 // renderer frame, assuming that the browser compositor will scale
124 // it back up to device scale. But on Android we put our browser layers in
125 // physical pixels and set our browser CC device_scale_factor to 1, so this
126 // suppresses the transform.
127 frame->delegated_frame_data->device_scale_factor = 1.0f;
129 gfx::Size frame_size =
130 frame->delegated_frame_data->render_pass_list.back()->output_rect.size();
131 bool size_changed = frame_size != frame_size_;
132 frame_size_ = frame_size;
134 if (!frame_provider_.get() || size_changed) {
135 if (delegated_layer_.get()) {
136 delegated_layer_->RemoveFromParent();
139 frame_provider_ = new cc::DelegatedFrameProvider(
140 resource_collection_.get(), frame->delegated_frame_data.Pass());
142 delegated_layer_ = cc::DelegatedRendererLayer::Create(
143 HardwareRendererLayerSettings(), frame_provider_);
144 delegated_layer_->SetBounds(frame_size_);
145 delegated_layer_->SetIsDrawable(true);
147 root_layer_->AddChild(delegated_layer_);
148 } else {
149 frame_provider_->SetFrameData(frame->delegated_frame_data.Pass());
153 void HardwareRenderer::DrawGL(bool stencil_enabled,
154 int framebuffer_binding_ext,
155 AwDrawGLInfo* draw_info) {
156 TRACE_EVENT0("android_webview", "HardwareRenderer::DrawGL");
158 // We need to watch if the current Android context has changed and enforce
159 // a clean-up in the compositor.
160 EGLContext current_context = eglGetCurrentContext();
161 DCHECK(current_context) << "DrawGL called without EGLContext";
163 // TODO(boliu): Handle context loss.
164 if (last_egl_context_ != current_context)
165 DLOG(WARNING) << "EGLContextChanged";
167 gfx::Transform transform(gfx::Transform::kSkipInitialization);
168 transform.matrix().setColMajorf(draw_info->transform);
169 transform.Translate(scroll_offset_.x(), scroll_offset_.y());
171 viewport_.SetSize(draw_info->width, draw_info->height);
172 // Need to post the new transform matrix back to child compositor
173 // because there is no onDraw during a Render Thread animation, and child
174 // compositor might not have the tiles rasterized as the animation goes on.
175 ParentCompositorDrawConstraints draw_constraints(
176 draw_info->is_layer, transform, gfx::Rect(viewport_));
177 if (!child_frame_.get() || draw_constraints.NeedUpdate(*child_frame_)) {
178 shared_renderer_state_->PostExternalDrawConstraintsToChildCompositorOnRT(
179 draw_constraints);
182 if (!delegated_layer_.get())
183 return;
185 layer_tree_host_->SetViewportSize(viewport_);
186 clip_.SetRect(draw_info->clip_left,
187 draw_info->clip_top,
188 draw_info->clip_right - draw_info->clip_left,
189 draw_info->clip_bottom - draw_info->clip_top);
190 stencil_enabled_ = stencil_enabled;
192 delegated_layer_->SetTransform(transform);
194 gl_surface_->SetBackingFrameBufferObject(framebuffer_binding_ext);
196 base::AutoReset<bool> frame_resetter(&viewport_clip_valid_for_dcheck_,
197 true);
198 layer_tree_host_->SetNeedsRedrawRect(clip_);
199 layer_tree_host_->Composite(base::TimeTicks::Now());
201 gl_surface_->ResetBackingFrameBufferObject();
204 void HardwareRenderer::RequestNewOutputSurface() {
205 scoped_refptr<cc::ContextProvider> context_provider =
206 AwRenderThreadContextProvider::Create(
207 gl_surface_, DeferredGpuCommandService::GetInstance());
208 scoped_ptr<ParentOutputSurface> output_surface_holder(
209 new ParentOutputSurface(context_provider));
210 output_surface_ = output_surface_holder.get();
211 layer_tree_host_->SetOutputSurface(output_surface_holder.Pass());
214 void HardwareRenderer::DidFailToInitializeOutputSurface() {
215 RequestNewOutputSurface();
218 void HardwareRenderer::UnusedResourcesAreAvailable() {
219 cc::ReturnedResourceArray returned_resources;
220 resource_collection_->TakeUnusedResourcesForChildCompositor(
221 &returned_resources);
222 shared_renderer_state_->InsertReturnedResourcesOnRT(returned_resources);
225 } // namespace android_webview