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

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: comments 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"
10 #include "base/debug/trace_event.h" 12 #include "base/debug/trace_event.h"
11 #include "base/strings/string_number_conversions.h" 13 #include "base/strings/string_number_conversions.h"
12 #include "content/public/browser/android/synchronous_compositor.h" 14 #include "cc/layers/delegated_frame_provider.h"
13 #include "content/public/browser/browser_thread.h" 15 #include "cc/layers/delegated_renderer_layer.h"
14 #include "gpu/command_buffer/service/shader_translator_cache.h" 16 #include "cc/layers/layer.h"
17 #include "cc/output/compositor_frame.h"
18 #include "cc/output/output_surface.h"
19 #include "cc/trees/layer_tree_host.h"
20 #include "cc/trees/layer_tree_settings.h"
21 #include "gpu/command_buffer/client/gl_in_process_context.h"
22 #include "ui/gfx/frame_time.h"
15 #include "ui/gfx/geometry/rect_conversions.h" 23 #include "ui/gfx/geometry/rect_conversions.h"
16 #include "ui/gfx/geometry/rect_f.h" 24 #include "ui/gfx/geometry/rect_f.h"
17 #include "ui/gfx/transform.h" 25 #include "ui/gfx/transform.h"
18 #include "ui/gl/gl_bindings.h" 26 #include "ui/gl/gl_bindings.h"
27 #include "webkit/common/gpu/context_provider_in_process.h"
28 #include "webkit/common/gpu/webgraphicscontext3d_in_process_command_buffer_impl. h"
19 29
20 namespace android_webview { 30 namespace android_webview {
21 31
32 namespace {
33
34 using webkit::gpu::WebGraphicsContext3DInProcessCommandBufferImpl;
35
36 scoped_refptr<cc::ContextProvider> CreateContext(
37 scoped_refptr<gfx::GLSurface> surface,
38 scoped_refptr<gpu::InProcessCommandBuffer::Service> service,
39 gpu::GLInProcessContext* share_context) {
40 const gfx::GpuPreference gpu_preference = gfx::PreferDiscreteGpu;
41
42 blink::WebGraphicsContext3D::Attributes attributes;
43 attributes.antialias = false;
44 attributes.depth = false;
45 attributes.stencil = false;
46 attributes.shareResources = true;
47 attributes.noAutomaticFlushes = true;
48 gpu::GLInProcessContextAttribs in_process_attribs;
49 WebGraphicsContext3DInProcessCommandBufferImpl::ConvertAttributes(
50 attributes, &in_process_attribs);
51 in_process_attribs.lose_context_when_out_of_memory = 1;
52
53 scoped_ptr<gpu::GLInProcessContext> context(
54 gpu::GLInProcessContext::Create(service,
55 surface,
56 surface->IsOffscreen(),
57 gfx::kNullAcceleratedWidget,
58 surface->GetSize(),
59 share_context,
60 false /* share_resources */,
61 in_process_attribs,
62 gpu_preference));
63 DCHECK(context.get());
64
65 return webkit::gpu::ContextProviderInProcess::Create(
66 WebGraphicsContext3DInProcessCommandBufferImpl::WrapContext(
67 context.Pass(), attributes),
68 "Parent-Compositor");
69 }
70
71 } // namespace
72
22 HardwareRenderer::HardwareRenderer(SharedRendererState* state) 73 HardwareRenderer::HardwareRenderer(SharedRendererState* state)
23 : shared_renderer_state_(state), 74 : shared_renderer_state_(state),
24 last_egl_context_(eglGetCurrentContext()) { 75 last_egl_context_(eglGetCurrentContext()),
76 view_width_(-1),
77 view_height_(-1),
78 root_layer_(cc::Layer::Create()) {
25 DCHECK(last_egl_context_); 79 DCHECK(last_egl_context_);
26 80
81 root_layer_->SetIsDrawable(false);
danakj 2014/05/20 21:50:02 this is the default already
boliu 2014/05/21 01:33:26 Done.
82
27 gl_surface_ = new AwGLSurface; 83 gl_surface_ = new AwGLSurface;
28 bool success = 84
29 shared_renderer_state_->GetCompositor()-> 85 cc::LayerTreeSettings settings;
30 InitializeHwDraw(gl_surface_); 86
31 DCHECK(success); 87 // Copied from compositor_impl_android.cc.
danakj 2014/05/20 21:50:02 Maybe you want a "Keep in sync with compositor_imp
88 settings.refresh_rate = 60.0;
89 settings.impl_side_painting = false;
90 settings.allow_antialiasing = false;
91 settings.calculate_top_controls_position = false;
danakj 2014/05/20 21:50:02 this is the default, should remove in both places?
92 settings.top_controls_height = 0.f;
danakj 2014/05/20 21:50:02 ditto
93 settings.highp_threshold_min = 2048;
94
95 // Android WebView uses system scrollbars, so make ours invisible.
96 settings.scrollbar_animator = cc::LayerTreeSettings::NoAnimator;
danakj 2014/05/20 21:50:02 ditto, also there are scrollbars in the browser co
boliu 2014/05/21 01:33:26 No scroll bar layers in parent compositor, removed
97 settings.solid_color_scrollbar_color = SK_ColorTRANSPARENT;
98
99 // Webview does not own the surface so should not clear it.
100 settings.should_clear_root_render_pass = false;
101
102 layer_tree_host_ =
103 cc::LayerTreeHost::CreateSingleThreaded(this, this, NULL, settings);
danakj 2014/05/20 21:50:02 you need a non-NULL HostSharedMemoryManager here.
boliu 2014/05/21 01:33:26 Ubercomp in webview is guaranteed to be hardware o
danakj 2014/05/21 15:22:54 What about non-resourceless software mode before y
boliu 2014/05/21 15:35:14 Right, webview either does resourceless software d
danakj 2014/05/21 15:36:32 Ohmygosh, I never even realized that. Ok thanks fo
104 layer_tree_host_->SetRootLayer(root_layer_);
105 layer_tree_host_->SetLayerTreeHostClientReady();
106
107 scoped_refptr<cc::ContextProvider> context_provider =
108 CreateContext(gl_surface_,
109 DeferredGpuCommandService::GetInstance(),
110 shared_renderer_state_->GetSharedContext());
111 output_surface_holder_.reset(new ParentOutputSurface(context_provider));
112 output_surface_ = output_surface_holder_->GetWeakPtr();
32 } 113 }
33 114
34 HardwareRenderer::~HardwareRenderer() { 115 HardwareRenderer::~HardwareRenderer() {
35 shared_renderer_state_->GetCompositor()->ReleaseHwDraw(); 116 layer_tree_host_->SetRootLayer(NULL);
danakj 2014/05/20 21:50:02 not really needed
boliu 2014/05/21 01:33:26 Removed.
36 gl_surface_ = NULL; 117 layer_tree_host_.reset();
118 root_layer_->RemoveAllChildren();
danakj 2014/05/20 21:50:02 why?
boliu 2014/05/21 01:33:26 Want to ensure DelegatedRendererLayer, which is a
119
120 // Order is important to ensure all resources are returned.
121 layer_ = NULL;
122 frame_provider_ = NULL;
123 if (resource_collection_.get()) {
124 #if DCHECK_IS_ON
125 // Check collection is empty.
126 cc::ReturnedResourceArray returned_resources;
127 resource_collection_->TakeUnusedResourcesForChildCompositor(
128 &returned_resources);
129 DCHECK(returned_resources.empty());
danakj 2014/05/20 21:50:02 nit: DCHECK_EQ(0, size()) gives you more data if i
boliu 2014/05/21 01:33:26 Done.
130 #endif // DCHECK_IS_ON
131
132 resource_collection_->SetClient(NULL);
133 }
37 } 134 }
38 135
39 bool HardwareRenderer::DrawGL(bool stencil_enabled, 136 bool HardwareRenderer::DrawGL(bool stencil_enabled,
40 int framebuffer_binding_ext, 137 int framebuffer_binding_ext,
41 AwDrawGLInfo* draw_info, 138 AwDrawGLInfo* draw_info,
42 DrawGLResult* result) { 139 DrawGLResult* result) {
43 TRACE_EVENT0("android_webview", "HardwareRenderer::DrawGL"); 140 TRACE_EVENT0("android_webview", "HardwareRenderer::DrawGL");
44 141
45 // We need to watch if the current Android context has changed and enforce 142 // We need to watch if the current Android context has changed and enforce
46 // a clean-up in the compositor. 143 // a clean-up in the compositor.
47 EGLContext current_context = eglGetCurrentContext(); 144 EGLContext current_context = eglGetCurrentContext();
48 if (!current_context) { 145 if (!current_context) {
49 DLOG(ERROR) << "DrawGL called without EGLContext"; 146 DLOG(ERROR) << "DrawGL called without EGLContext";
50 return false; 147 return false;
51 } 148 }
52 149
53 // TODO(boliu): Handle context loss. 150 // TODO(boliu): Handle context loss.
54 if (last_egl_context_ != current_context) 151 if (last_egl_context_ != current_context)
55 DLOG(WARNING) << "EGLContextChanged"; 152 DLOG(WARNING) << "EGLContextChanged";
56 153
57 if (draw_info->mode != AwDrawGLInfo::kModeDraw) 154 scoped_ptr<DrawGLInput> input = shared_renderer_state_->PassDrawGLInput();
58 return false; 155 if (!resource_collection_.get()) {
156 resource_collection_ = new cc::DelegatedFrameResourceCollection;
157 resource_collection_->SetClient(this);
158 }
59 159
60 // Should only need to access SharedRendererState in kModeDraw and kModeSync. 160 if (input.get()) {
61 const DrawGLInput input = shared_renderer_state_->GetDrawGLInput(); 161 DCHECK(!input->frame.gl_frame_data);
62 SetCompositorMemoryPolicy(); 162 DCHECK(!input->frame.software_frame_data);
63 163
64 gl_surface_->SetBackingFrameBufferObject(framebuffer_binding_ext); 164 bool size_changed =
165 input->width != view_width_ || input->height != view_height_;
166 view_width_ = input->width;
167 view_height_ = input->height;
168 scroll_offset_ = input->scroll_offset;
65 169
66 gfx::Transform transform; 170 if (!frame_provider_ || size_changed) {
67 transform.matrix().setColMajorf(draw_info->transform); 171 if (layer_) {
68 transform.Translate(input.scroll_offset.x(), input.scroll_offset.y()); 172 layer_->RemoveFromParent();
173 }
174
175 frame_provider_ = new cc::DelegatedFrameProvider(
176 resource_collection_.get(), input->frame.delegated_frame_data.Pass());
177
178 layer_ = cc::DelegatedRendererLayer::Create(frame_provider_);
179 layer_->SetBounds(gfx::Size(view_width_, view_height_));
180 layer_->SetIsDrawable(true);
181 layer_->SetAnchorPoint(gfx::PointF(0.f, 0.f));
182
183 root_layer_->AddChild(layer_);
184 } else {
185 frame_provider_->SetFrameData(input->frame.delegated_frame_data.Pass());
186 }
187 }
188
189 gfx::Size viewport(draw_info->width, draw_info->height);
190 layer_tree_host_->SetViewportSize(viewport);
69 gfx::Rect clip_rect(draw_info->clip_left, 191 gfx::Rect clip_rect(draw_info->clip_left,
70 draw_info->clip_top, 192 draw_info->clip_top,
71 draw_info->clip_right - draw_info->clip_left, 193 draw_info->clip_right - draw_info->clip_left,
72 draw_info->clip_bottom - draw_info->clip_top); 194 draw_info->clip_bottom - draw_info->clip_top);
195 DCHECK(output_surface_);
196 if (output_surface_) {
no sievers 2014/05/20 20:48:26 Either DCHECK() or if
danakj 2014/05/20 21:50:02 Why do we need a weakptr here. If the OutputSurfac
boliu 2014/05/21 01:33:26 DCHECK.
197 output_surface_->SetDrawConstraints(viewport, clip_rect);
danakj 2014/05/20 21:50:02 future: maybe we could make these inputs to Compos
boliu 2014/05/21 01:33:26 Hmm, this is mirroring how webview sets the viewpo
danakj 2014/05/21 15:22:54 Ah, it wasn't clear that the renderer would still
198 }
199 gfx::Transform transform(gfx::Transform::kSkipInitialization);
200 transform.matrix().setColMajorf(draw_info->transform);
201 transform.Translate(scroll_offset_.x(), scroll_offset_.y());
202 layer_->SetTransform(transform);
73 203
74 gfx::Rect viewport(draw_info->width, draw_info->height); 204 gl_surface_->SetBackingFrameBufferObject(framebuffer_binding_ext);
75 if (!draw_info->is_layer) { 205 layer_tree_host_->Composite(gfx::FrameTime::Now());
76 gfx::RectF view_rect(input.width, input.height);
77 transform.TransformRect(&view_rect);
78 viewport.Intersect(gfx::ToEnclosingRect(view_rect));
79 }
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(); 206 gl_surface_->ResetBackingFrameBufferObject();
88 207
89 if (did_draw) { 208 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 } 209 }
96 210
97 void HardwareRenderer::SetCompositorMemoryPolicy() { 211 scoped_ptr<cc::OutputSurface> HardwareRenderer::CreateOutputSurface(
98 if (shared_renderer_state_->IsMemoryPolicyDirty()) { 212 bool fallback) {
99 content::SynchronousCompositorMemoryPolicy policy = 213 // Android webview does not lose output surface.
no sievers 2014/05/20 20:48:26 nit: does not *support* losing the output surface
boliu 2014/05/21 01:33:26 Heh, ok.
100 shared_renderer_state_->GetMemoryPolicy(); 214 DCHECK(!fallback);
101 // Memory policy is set by BrowserViewRenderer on UI thread. 215 DCHECK(output_surface_holder_.get());
102 shared_renderer_state_->GetCompositor()->SetMemoryPolicy(policy); 216 return output_surface_holder_.PassAs<cc::OutputSurface>();
103 shared_renderer_state_->SetMemoryPolicyDirty(false); 217 }
104 } 218
219 void HardwareRenderer::UnusedResourcesAreAvailable() {
220 cc::ReturnedResourceArray returned_resources;
221 resource_collection_->TakeUnusedResourcesForChildCompositor(
222 &returned_resources);
223 shared_renderer_state_->InsertReturnedResources(returned_resources);
105 } 224 }
106 225
107 } // namespace android_webview 226 } // namespace android_webview
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698