Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(875)

Side by Side Diff: android_webview/browser/hardware_renderer.cc

Issue 287993004: [Android WebView] Implement Ubercomp for Render Thread support (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: review Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 "android_webview/browser/aw_gl_surface.h" 7 #include "android_webview/browser/aw_gl_surface.h"
8 #include "android_webview/browser/browser_view_renderer_client.h" 8 #include "android_webview/browser/deferred_gpu_command_service.h"
9 #include "android_webview/browser/parent_output_surface.h"
10 #include "android_webview/browser/shared_renderer_state.h"
9 #include "android_webview/public/browser/draw_gl.h" 11 #include "android_webview/public/browser/draw_gl.h"
12 #include "base/auto_reset.h"
10 #include "base/debug/trace_event.h" 13 #include "base/debug/trace_event.h"
11 #include "base/strings/string_number_conversions.h" 14 #include "base/strings/string_number_conversions.h"
12 #include "content/public/browser/android/synchronous_compositor.h" 15 #include "cc/layers/delegated_frame_provider.h"
13 #include "content/public/browser/browser_thread.h" 16 #include "cc/layers/delegated_renderer_layer.h"
14 #include "gpu/command_buffer/service/shader_translator_cache.h" 17 #include "cc/layers/layer.h"
18 #include "cc/output/compositor_frame.h"
19 #include "cc/output/output_surface.h"
20 #include "cc/trees/layer_tree_host.h"
21 #include "cc/trees/layer_tree_settings.h"
22 #include "gpu/command_buffer/client/gl_in_process_context.h"
23 #include "ui/gfx/frame_time.h"
15 #include "ui/gfx/geometry/rect_conversions.h" 24 #include "ui/gfx/geometry/rect_conversions.h"
16 #include "ui/gfx/geometry/rect_f.h" 25 #include "ui/gfx/geometry/rect_f.h"
17 #include "ui/gfx/transform.h" 26 #include "ui/gfx/transform.h"
18 #include "ui/gl/gl_bindings.h" 27 #include "ui/gl/gl_bindings.h"
28 #include "webkit/common/gpu/context_provider_in_process.h"
29 #include "webkit/common/gpu/webgraphicscontext3d_in_process_command_buffer_impl. h"
19 30
20 namespace android_webview { 31 namespace android_webview {
21 32
33 namespace {
34
35 using webkit::gpu::WebGraphicsContext3DInProcessCommandBufferImpl;
36
37 scoped_refptr<cc::ContextProvider> CreateContext(
38 scoped_refptr<gfx::GLSurface> surface,
39 scoped_refptr<gpu::InProcessCommandBuffer::Service> service,
40 gpu::GLInProcessContext* share_context) {
41 const gfx::GpuPreference gpu_preference = gfx::PreferDiscreteGpu;
42
43 blink::WebGraphicsContext3D::Attributes attributes;
44 attributes.antialias = false;
45 attributes.depth = false;
46 attributes.stencil = false;
47 attributes.shareResources = true;
48 attributes.noAutomaticFlushes = true;
49 gpu::GLInProcessContextAttribs in_process_attribs;
50 WebGraphicsContext3DInProcessCommandBufferImpl::ConvertAttributes(
51 attributes, &in_process_attribs);
52 in_process_attribs.lose_context_when_out_of_memory = 1;
53
54 scoped_ptr<gpu::GLInProcessContext> context(
55 gpu::GLInProcessContext::Create(service,
56 surface,
57 surface->IsOffscreen(),
58 gfx::kNullAcceleratedWidget,
59 surface->GetSize(),
60 share_context,
61 false /* share_resources */,
62 in_process_attribs,
63 gpu_preference));
64 DCHECK(context.get());
65
66 return webkit::gpu::ContextProviderInProcess::Create(
67 WebGraphicsContext3DInProcessCommandBufferImpl::WrapContext(
68 context.Pass(), attributes),
69 "Parent-Compositor");
70 }
71
72 } // namespace
73
22 HardwareRenderer::HardwareRenderer(SharedRendererState* state) 74 HardwareRenderer::HardwareRenderer(SharedRendererState* state)
23 : shared_renderer_state_(state), 75 : shared_renderer_state_(state),
24 last_egl_context_(eglGetCurrentContext()) { 76 last_egl_context_(eglGetCurrentContext()),
77 view_width_(-1),
78 view_height_(-1),
79 viewport_clip_valid_for_dcheck_(false),
80 root_layer_(cc::Layer::Create()),
81 output_surface_(NULL) {
25 DCHECK(last_egl_context_); 82 DCHECK(last_egl_context_);
26 83
27 gl_surface_ = new AwGLSurface; 84 gl_surface_ = new AwGLSurface;
28 bool success = 85
29 shared_renderer_state_->GetCompositor()-> 86 cc::LayerTreeSettings settings;
30 InitializeHwDraw(gl_surface_); 87
31 DCHECK(success); 88 // Copied from compositor_impl_android.cc.
89 settings.refresh_rate = 60.0;
90 settings.impl_side_painting = false;
91 settings.allow_antialiasing = false;
92 settings.calculate_top_controls_position = false;
93 settings.top_controls_height = 0.f;
94 settings.highp_threshold_min = 2048;
boliu 2014/05/21 19:58:22 refresh_rate impl_side_painting calculate_top_cont
boliu 2014/05/21 20:00:26 Argg...those are removed due to same as default.
95
96 // Webview does not own the surface so should not clear it.
97 settings.should_clear_root_render_pass = false;
98
99 layer_tree_host_ =
100 cc::LayerTreeHost::CreateSingleThreaded(this, this, NULL, settings);
101 layer_tree_host_->SetRootLayer(root_layer_);
102 layer_tree_host_->SetLayerTreeHostClientReady();
32 } 103 }
33 104
34 HardwareRenderer::~HardwareRenderer() { 105 HardwareRenderer::~HardwareRenderer() {
35 shared_renderer_state_->GetCompositor()->ReleaseHwDraw(); 106 // Must reset everything before |resource_collection_| to ensure all
36 gl_surface_ = NULL; 107 // resources are returned before resetting |resource_collection_| client.
108 layer_tree_host_.reset();
109 root_layer_ = NULL;
110 delegated_layer_ = NULL;
111 frame_provider_ = NULL;
112 if (resource_collection_.get()) {
113 #if DCHECK_IS_ON
114 // Check collection is empty.
115 cc::ReturnedResourceArray returned_resources;
116 resource_collection_->TakeUnusedResourcesForChildCompositor(
117 &returned_resources);
118 DCHECK_EQ(0, returned_resources.size());
119 #endif // DCHECK_IS_ON
120
121 resource_collection_->SetClient(NULL);
122 }
123 }
124
125 void HardwareRenderer::DidBeginMainFrame() {
126 // This is called after OutputSurface is created, but before the impl frame
127 // starts. We set the draw constraints here.
128 DCHECK(output_surface_);
129 DCHECK(viewport_clip_valid_for_dcheck_);
130 output_surface_->SetDrawConstraints(viewport_, clip_);
37 } 131 }
38 132
39 bool HardwareRenderer::DrawGL(bool stencil_enabled, 133 bool HardwareRenderer::DrawGL(bool stencil_enabled,
40 int framebuffer_binding_ext, 134 int framebuffer_binding_ext,
41 AwDrawGLInfo* draw_info, 135 AwDrawGLInfo* draw_info,
42 DrawGLResult* result) { 136 DrawGLResult* result) {
43 TRACE_EVENT0("android_webview", "HardwareRenderer::DrawGL"); 137 TRACE_EVENT0("android_webview", "HardwareRenderer::DrawGL");
44 138
45 // We need to watch if the current Android context has changed and enforce 139 // We need to watch if the current Android context has changed and enforce
46 // a clean-up in the compositor. 140 // a clean-up in the compositor.
47 EGLContext current_context = eglGetCurrentContext(); 141 EGLContext current_context = eglGetCurrentContext();
48 if (!current_context) { 142 if (!current_context) {
49 DLOG(ERROR) << "DrawGL called without EGLContext"; 143 DLOG(ERROR) << "DrawGL called without EGLContext";
50 return false; 144 return false;
51 } 145 }
52 146
53 // TODO(boliu): Handle context loss. 147 // TODO(boliu): Handle context loss.
54 if (last_egl_context_ != current_context) 148 if (last_egl_context_ != current_context)
55 DLOG(WARNING) << "EGLContextChanged"; 149 DLOG(WARNING) << "EGLContextChanged";
56 150
57 if (draw_info->mode != AwDrawGLInfo::kModeDraw) 151 scoped_ptr<DrawGLInput> input = shared_renderer_state_->PassDrawGLInput();
58 return false; 152 if (!resource_collection_.get()) {
153 resource_collection_ = new cc::DelegatedFrameResourceCollection;
154 resource_collection_->SetClient(this);
155 }
59 156
60 // Should only need to access SharedRendererState in kModeDraw and kModeSync. 157 if (input.get()) {
61 const DrawGLInput input = shared_renderer_state_->GetDrawGLInput(); 158 DCHECK(!input->frame.gl_frame_data);
62 SetCompositorMemoryPolicy(); 159 DCHECK(!input->frame.software_frame_data);
160
161 bool size_changed =
162 input->width != view_width_ || input->height != view_height_;
163 view_width_ = input->width;
164 view_height_ = input->height;
165 scroll_offset_ = input->scroll_offset;
166
167 if (!frame_provider_ || size_changed) {
168 if (delegated_layer_) {
169 delegated_layer_->RemoveFromParent();
170 }
171
172 frame_provider_ = new cc::DelegatedFrameProvider(
173 resource_collection_.get(), input->frame.delegated_frame_data.Pass());
174
175 delegated_layer_ = cc::DelegatedRendererLayer::Create(frame_provider_);
176 delegated_layer_->SetBounds(gfx::Size(view_width_, view_height_));
177 delegated_layer_->SetIsDrawable(true);
178 delegated_layer_->SetAnchorPoint(gfx::PointF(0.f, 0.f));
179
180 root_layer_->AddChild(delegated_layer_);
181 } else {
182 frame_provider_->SetFrameData(input->frame.delegated_frame_data.Pass());
183 }
184 }
185
186 viewport_.SetSize(draw_info->width, draw_info->height);
187 layer_tree_host_->SetViewportSize(viewport_);
188 clip_.SetRect(draw_info->clip_left,
189 draw_info->clip_top,
190 draw_info->clip_right - draw_info->clip_left,
191 draw_info->clip_bottom - draw_info->clip_top);
192
193 gfx::Transform transform(gfx::Transform::kSkipInitialization);
194 transform.matrix().setColMajorf(draw_info->transform);
195 transform.Translate(scroll_offset_.x(), scroll_offset_.y());
196 delegated_layer_->SetTransform(transform);
63 197
64 gl_surface_->SetBackingFrameBufferObject(framebuffer_binding_ext); 198 gl_surface_->SetBackingFrameBufferObject(framebuffer_binding_ext);
65 199 {
66 gfx::Transform transform; 200 base::AutoReset<bool> frame_resetter(&viewport_clip_valid_for_dcheck_,
67 transform.matrix().setColMajorf(draw_info->transform); 201 true);
68 transform.Translate(input.scroll_offset.x(), input.scroll_offset.y()); 202 layer_tree_host_->Composite(gfx::FrameTime::Now());
69 gfx::Rect clip_rect(draw_info->clip_left,
70 draw_info->clip_top,
71 draw_info->clip_right - draw_info->clip_left,
72 draw_info->clip_bottom - draw_info->clip_top);
73
74 gfx::Rect viewport(draw_info->width, draw_info->height);
75 if (!draw_info->is_layer) {
76 gfx::RectF view_rect(input.width, input.height);
77 transform.TransformRect(&view_rect);
78 viewport.Intersect(gfx::ToEnclosingRect(view_rect));
79 } 203 }
80
81 bool did_draw = shared_renderer_state_->GetCompositor()->DemandDrawHw(
82 gfx::Size(draw_info->width, draw_info->height),
83 transform,
84 viewport,
85 clip_rect,
86 stencil_enabled);
87 gl_surface_->ResetBackingFrameBufferObject(); 204 gl_surface_->ResetBackingFrameBufferObject();
88 205
89 if (did_draw) { 206 return true;
90 result->frame_id = input.frame_id;
91 result->clip_contains_visible_rect =
92 clip_rect.Contains(input.global_visible_rect);
93 }
94 return did_draw;
95 } 207 }
96 208
97 void HardwareRenderer::SetCompositorMemoryPolicy() { 209 scoped_ptr<cc::OutputSurface> HardwareRenderer::CreateOutputSurface(
98 if (shared_renderer_state_->IsMemoryPolicyDirty()) { 210 bool fallback) {
99 content::SynchronousCompositorMemoryPolicy policy = 211 // Android webview does not support losing output surface.
100 shared_renderer_state_->GetMemoryPolicy(); 212 DCHECK(!fallback);
101 // Memory policy is set by BrowserViewRenderer on UI thread. 213 scoped_refptr<cc::ContextProvider> context_provider =
102 shared_renderer_state_->GetCompositor()->SetMemoryPolicy(policy); 214 CreateContext(gl_surface_,
103 shared_renderer_state_->SetMemoryPolicyDirty(false); 215 DeferredGpuCommandService::GetInstance(),
104 } 216 shared_renderer_state_->GetSharedContext());
217 scoped_ptr<ParentOutputSurface> output_surface_holder_(
danakj 2014/05/21 15:45:39 remove _ suffix
boliu 2014/05/21 19:58:22 Done.
218 new ParentOutputSurface(context_provider));
219 output_surface_ = output_surface_holder_.get();
220 return output_surface_holder_.PassAs<cc::OutputSurface>();
221 }
222
223 void HardwareRenderer::UnusedResourcesAreAvailable() {
224 cc::ReturnedResourceArray returned_resources;
225 resource_collection_->TakeUnusedResourcesForChildCompositor(
226 &returned_resources);
227 shared_renderer_state_->InsertReturnedResources(returned_resources);
105 } 228 }
106 229
107 } // namespace android_webview 230 } // namespace android_webview
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698