Update V8 to version 4.7.19.
[chromium-blink-merge.git] / android_webview / browser / hardware_renderer.cc
blobeca386e6e4bb845c9969c28bee2bb6f0b8c051a6
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();
77 scoped_ptr<ChildFrame> child_frame =
78 shared_renderer_state_->PassCompositorFrameOnRT();
79 if (!child_frame.get())
80 return;
81 child_frame_ = child_frame.Pass();
84 scoped_ptr<cc::CompositorFrame> frame = child_frame_->frame.Pass();
85 DCHECK(frame.get());
86 DCHECK(!frame->gl_frame_data);
88 // On Android we put our browser layers in physical pixels and set our
89 // browser CC device_scale_factor to 1, so suppress the transform between
90 // DIP and pixels.
91 frame->delegated_frame_data->device_scale_factor = 1.0f;
93 gfx::Size frame_size =
94 frame->delegated_frame_data->render_pass_list.back()->output_rect.size();
95 bool size_changed = frame_size != frame_size_;
96 frame_size_ = frame_size;
97 if (child_id_.is_null() || size_changed) {
98 if (!child_id_.is_null())
99 surface_factory_->Destroy(child_id_);
100 child_id_ = surface_id_allocator_->GenerateId();
101 surface_factory_->Create(child_id_);
104 surface_factory_->SubmitCompositorFrame(child_id_, frame.Pass(),
105 cc::SurfaceFactory::DrawCallback());
108 void HardwareRenderer::DrawGL(bool stencil_enabled,
109 int framebuffer_binding_ext,
110 AwDrawGLInfo* draw_info) {
111 TRACE_EVENT0("android_webview", "HardwareRenderer::DrawGL");
113 // We need to watch if the current Android context has changed and enforce
114 // a clean-up in the compositor.
115 EGLContext current_context = eglGetCurrentContext();
116 DCHECK(current_context) << "DrawGL called without EGLContext";
118 // TODO(boliu): Handle context loss.
119 if (last_egl_context_ != current_context)
120 DLOG(WARNING) << "EGLContextChanged";
122 gfx::Transform transform(gfx::Transform::kSkipInitialization);
123 transform.matrix().setColMajorf(draw_info->transform);
124 transform.Translate(scroll_offset_.x(), scroll_offset_.y());
126 gfx::Size viewport(draw_info->width, draw_info->height);
127 // Need to post the new transform matrix back to child compositor
128 // because there is no onDraw during a Render Thread animation, and child
129 // compositor might not have the tiles rasterized as the animation goes on.
130 ParentCompositorDrawConstraints draw_constraints(
131 draw_info->is_layer, transform, viewport.IsEmpty());
132 if (!child_frame_.get() || draw_constraints.NeedUpdate(*child_frame_)) {
133 shared_renderer_state_->PostExternalDrawConstraintsToChildCompositorOnRT(
134 draw_constraints);
137 if (child_id_.is_null())
138 return;
140 gfx::Rect clip(draw_info->clip_left, draw_info->clip_top,
141 draw_info->clip_right - draw_info->clip_left,
142 draw_info->clip_bottom - draw_info->clip_top);
144 // Create a frame with a single SurfaceDrawQuad referencing the child
145 // Surface and transformed using the given transform.
146 scoped_ptr<cc::RenderPass> render_pass = cc::RenderPass::Create();
147 render_pass->SetAll(cc::RenderPassId(1, 1), gfx::Rect(viewport), clip,
148 gfx::Transform(), true);
150 cc::SharedQuadState* quad_state =
151 render_pass->CreateAndAppendSharedQuadState();
152 quad_state->quad_to_target_transform = transform;
153 quad_state->quad_layer_bounds = frame_size_;
154 quad_state->visible_quad_layer_rect = gfx::Rect(frame_size_);
155 quad_state->opacity = 1.f;
157 cc::SurfaceDrawQuad* surface_quad =
158 render_pass->CreateAndAppendDrawQuad<cc::SurfaceDrawQuad>();
159 surface_quad->SetNew(quad_state, gfx::Rect(quad_state->quad_layer_bounds),
160 gfx::Rect(quad_state->quad_layer_bounds), child_id_);
162 scoped_ptr<cc::DelegatedFrameData> delegated_frame(
163 new cc::DelegatedFrameData);
164 delegated_frame->render_pass_list.push_back(render_pass.Pass());
165 scoped_ptr<cc::CompositorFrame> frame(new cc::CompositorFrame);
166 frame->delegated_frame_data = delegated_frame.Pass();
168 if (root_id_.is_null()) {
169 root_id_ = surface_id_allocator_->GenerateId();
170 surface_factory_->Create(root_id_);
171 display_->SetSurfaceId(root_id_, 1.f);
173 surface_factory_->SubmitCompositorFrame(root_id_, frame.Pass(),
174 cc::SurfaceFactory::DrawCallback());
176 display_->Resize(viewport);
178 gl_surface_->SetBackingFrameBufferObject(framebuffer_binding_ext);
179 if (!output_surface_) {
180 scoped_refptr<cc::ContextProvider> context_provider =
181 AwRenderThreadContextProvider::Create(
182 gl_surface_, DeferredGpuCommandService::GetInstance());
183 scoped_ptr<ParentOutputSurface> output_surface_holder(
184 new ParentOutputSurface(context_provider));
185 output_surface_ = output_surface_holder.get();
186 display_->Initialize(output_surface_holder.Pass(), nullptr);
188 output_surface_->SetExternalStencilTest(stencil_enabled);
189 display_->SetExternalClip(clip);
190 display_->DrawAndSwap();
191 gl_surface_->ResetBackingFrameBufferObject();
194 void HardwareRenderer::ReturnResources(
195 const cc::ReturnedResourceArray& resources) {
196 shared_renderer_state_->InsertReturnedResourcesOnRT(resources);
199 } // namespace android_webview