Update V8 to version 4.7.57.
[chromium-blink-merge.git] / android_webview / browser / hardware_renderer.cc
blob5979a1eb2237e4aab0cf1461967c5fa2a0b76e2d
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/output/compositor_frame.h"
19 #include "cc/output/output_surface.h"
20 #include "cc/output/renderer_settings.h"
21 #include "cc/quads/shared_quad_state.h"
22 #include "cc/quads/surface_draw_quad.h"
23 #include "cc/surfaces/display.h"
24 #include "cc/surfaces/surface_factory.h"
25 #include "cc/surfaces/surface_id_allocator.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 android_webview {
35 HardwareRenderer::HardwareRenderer(SharedRendererState* state)
36 : shared_renderer_state_(state),
37 last_egl_context_(eglGetCurrentContext()),
38 gl_surface_(new AwGLSurface),
39 output_surface_(NULL) {
40 DCHECK(last_egl_context_);
42 cc::RendererSettings settings;
44 // Should be kept in sync with compositor_impl_android.cc.
45 settings.allow_antialiasing = false;
46 settings.highp_threshold_min = 2048;
48 // Webview does not own the surface so should not clear it.
49 settings.should_clear_root_render_pass = false;
51 surface_manager_.reset(new cc::SurfaceManager);
52 surface_id_allocator_.reset(new cc::SurfaceIdAllocator(1));
53 display_.reset(new cc::Display(this, surface_manager_.get(), nullptr, nullptr,
54 settings));
55 surface_factory_.reset(new cc::SurfaceFactory(surface_manager_.get(), this));
58 HardwareRenderer::~HardwareRenderer() {
59 // Must reset everything before |surface_factory_| to ensure all
60 // resources are returned before resetting.
61 if (!root_id_.is_null())
62 surface_factory_->Destroy(root_id_);
63 if (!child_id_.is_null())
64 surface_factory_->Destroy(child_id_);
65 display_.reset();
66 surface_factory_.reset();
68 // Reset draw constraints.
69 shared_renderer_state_->PostExternalDrawConstraintsToChildCompositorOnRT(
70 ParentCompositorDrawConstraints());
73 void HardwareRenderer::CommitFrame() {
74 TRACE_EVENT0("android_webview", "CommitFrame");
75 scroll_offset_ = shared_renderer_state_->GetScrollOffsetOnRT();
76 scoped_ptr<ChildFrame> child_frame =
77 shared_renderer_state_->PassCompositorFrameOnRT();
78 if (!child_frame.get())
79 return;
80 child_frame_ = child_frame.Pass();
81 DCHECK(child_frame_->frame.get());
82 DCHECK(!child_frame_->frame->gl_frame_data);
85 void HardwareRenderer::DrawGL(bool stencil_enabled,
86 AwDrawGLInfo* draw_info) {
87 TRACE_EVENT0("android_webview", "HardwareRenderer::DrawGL");
89 // We need to watch if the current Android context has changed and enforce
90 // a clean-up in the compositor.
91 EGLContext current_context = eglGetCurrentContext();
92 DCHECK(current_context) << "DrawGL called without EGLContext";
94 // TODO(boliu): Handle context loss.
95 if (last_egl_context_ != current_context)
96 DLOG(WARNING) << "EGLContextChanged";
98 // SurfaceFactory::SubmitCompositorFrame might call glFlush. So calling it
99 // during "kModeSync" stage (which does not allow GL) might result in extra
100 // kModeProcess. Instead, submit the frame in "kModeDraw" stage to avoid
101 // unnecessary kModeProcess.
102 scoped_ptr<ChildFrame> child_frame = child_frame_.Pass();
103 if (child_frame.get()) {
104 scoped_ptr<cc::CompositorFrame> child_compositor_frame =
105 child_frame->frame.Pass();
107 // On Android we put our browser layers in physical pixels and set our
108 // browser CC device_scale_factor to 1, so suppress the transform between
109 // DIP and pixels.
110 child_compositor_frame->delegated_frame_data->device_scale_factor = 1.0f;
112 gfx::Size frame_size =
113 child_compositor_frame->delegated_frame_data->render_pass_list.back()
114 ->output_rect.size();
115 bool size_changed = frame_size != frame_size_;
116 frame_size_ = frame_size;
117 if (child_id_.is_null() || size_changed) {
118 if (!child_id_.is_null())
119 surface_factory_->Destroy(child_id_);
120 child_id_ = surface_id_allocator_->GenerateId();
121 surface_factory_->Create(child_id_);
124 surface_factory_->SubmitCompositorFrame(child_id_,
125 child_compositor_frame.Pass(),
126 cc::SurfaceFactory::DrawCallback());
129 gfx::Transform transform(gfx::Transform::kSkipInitialization);
130 transform.matrix().setColMajorf(draw_info->transform);
131 transform.Translate(scroll_offset_.x(), scroll_offset_.y());
133 gfx::Size viewport(draw_info->width, draw_info->height);
134 // Need to post the new transform matrix back to child compositor
135 // because there is no onDraw during a Render Thread animation, and child
136 // compositor might not have the tiles rasterized as the animation goes on.
137 ParentCompositorDrawConstraints draw_constraints(
138 draw_info->is_layer, transform, viewport.IsEmpty());
139 if (!child_frame.get() || draw_constraints.NeedUpdate(*child_frame)) {
140 shared_renderer_state_->PostExternalDrawConstraintsToChildCompositorOnRT(
141 draw_constraints);
144 if (child_id_.is_null())
145 return;
147 gfx::Rect clip(draw_info->clip_left, draw_info->clip_top,
148 draw_info->clip_right - draw_info->clip_left,
149 draw_info->clip_bottom - draw_info->clip_top);
151 // Create a frame with a single SurfaceDrawQuad referencing the child
152 // Surface and transformed using the given transform.
153 scoped_ptr<cc::RenderPass> render_pass = cc::RenderPass::Create();
154 render_pass->SetAll(cc::RenderPassId(1, 1), gfx::Rect(viewport), clip,
155 gfx::Transform(), true);
157 cc::SharedQuadState* quad_state =
158 render_pass->CreateAndAppendSharedQuadState();
159 quad_state->quad_to_target_transform = transform;
160 quad_state->quad_layer_bounds = frame_size_;
161 quad_state->visible_quad_layer_rect = gfx::Rect(frame_size_);
162 quad_state->opacity = 1.f;
164 cc::SurfaceDrawQuad* surface_quad =
165 render_pass->CreateAndAppendDrawQuad<cc::SurfaceDrawQuad>();
166 surface_quad->SetNew(quad_state, gfx::Rect(quad_state->quad_layer_bounds),
167 gfx::Rect(quad_state->quad_layer_bounds), child_id_);
169 scoped_ptr<cc::DelegatedFrameData> delegated_frame(
170 new cc::DelegatedFrameData);
171 delegated_frame->render_pass_list.push_back(render_pass.Pass());
172 scoped_ptr<cc::CompositorFrame> frame(new cc::CompositorFrame);
173 frame->delegated_frame_data = delegated_frame.Pass();
175 if (root_id_.is_null()) {
176 root_id_ = surface_id_allocator_->GenerateId();
177 surface_factory_->Create(root_id_);
178 display_->SetSurfaceId(root_id_, 1.f);
180 surface_factory_->SubmitCompositorFrame(root_id_, frame.Pass(),
181 cc::SurfaceFactory::DrawCallback());
183 display_->Resize(viewport);
185 if (!output_surface_) {
186 scoped_refptr<cc::ContextProvider> context_provider =
187 AwRenderThreadContextProvider::Create(
188 gl_surface_, DeferredGpuCommandService::GetInstance());
189 scoped_ptr<ParentOutputSurface> output_surface_holder(
190 new ParentOutputSurface(context_provider));
191 output_surface_ = output_surface_holder.get();
192 display_->Initialize(output_surface_holder.Pass(), nullptr);
194 output_surface_->SetExternalStencilTest(stencil_enabled);
195 display_->SetExternalClip(clip);
196 display_->DrawAndSwap();
199 void HardwareRenderer::ReturnResources(
200 const cc::ReturnedResourceArray& resources) {
201 shared_renderer_state_->InsertReturnedResourcesOnRT(resources);
204 void HardwareRenderer::SetBackingFrameBufferObject(
205 int framebuffer_binding_ext) {
206 gl_surface_->SetBackingFrameBufferObject(framebuffer_binding_ext);
209 } // namespace android_webview