Chromium Code Reviews| Index: android_webview/browser/hardware_renderer.cc |
| diff --git a/android_webview/browser/hardware_renderer.cc b/android_webview/browser/hardware_renderer.cc |
| index f2cf8e90b17cec80a443857cd5dfff71a943bc9a..15052ce5b0e61facaa739c8571d59955910a33d6 100644 |
| --- a/android_webview/browser/hardware_renderer.cc |
| +++ b/android_webview/browser/hardware_renderer.cc |
| @@ -5,35 +5,132 @@ |
| #include "android_webview/browser/hardware_renderer.h" |
| #include "android_webview/browser/aw_gl_surface.h" |
| -#include "android_webview/browser/browser_view_renderer_client.h" |
| +#include "android_webview/browser/deferred_gpu_command_service.h" |
| +#include "android_webview/browser/parent_output_surface.h" |
| +#include "android_webview/browser/shared_renderer_state.h" |
| #include "android_webview/public/browser/draw_gl.h" |
| #include "base/debug/trace_event.h" |
| #include "base/strings/string_number_conversions.h" |
| -#include "content/public/browser/android/synchronous_compositor.h" |
| -#include "content/public/browser/browser_thread.h" |
| -#include "gpu/command_buffer/service/shader_translator_cache.h" |
| +#include "cc/layers/delegated_frame_provider.h" |
| +#include "cc/layers/delegated_renderer_layer.h" |
| +#include "cc/layers/layer.h" |
| +#include "cc/output/compositor_frame.h" |
| +#include "cc/output/output_surface.h" |
| +#include "cc/trees/layer_tree_host.h" |
| +#include "cc/trees/layer_tree_settings.h" |
| +#include "gpu/command_buffer/client/gl_in_process_context.h" |
| +#include "ui/gfx/frame_time.h" |
| #include "ui/gfx/geometry/rect_conversions.h" |
| #include "ui/gfx/geometry/rect_f.h" |
| #include "ui/gfx/transform.h" |
| #include "ui/gl/gl_bindings.h" |
| +#include "webkit/common/gpu/context_provider_in_process.h" |
| +#include "webkit/common/gpu/webgraphicscontext3d_in_process_command_buffer_impl.h" |
| namespace android_webview { |
| +namespace { |
| + |
| +using webkit::gpu::WebGraphicsContext3DInProcessCommandBufferImpl; |
| + |
| +scoped_refptr<cc::ContextProvider> CreateContext( |
| + scoped_refptr<gfx::GLSurface> surface, |
| + scoped_refptr<gpu::InProcessCommandBuffer::Service> service, |
| + gpu::GLInProcessContext* share_context) { |
| + const gfx::GpuPreference gpu_preference = gfx::PreferDiscreteGpu; |
| + |
| + blink::WebGraphicsContext3D::Attributes attributes; |
| + attributes.antialias = false; |
| + attributes.depth = false; |
| + attributes.stencil = false; |
| + attributes.shareResources = true; |
| + attributes.noAutomaticFlushes = true; |
| + gpu::GLInProcessContextAttribs in_process_attribs; |
| + WebGraphicsContext3DInProcessCommandBufferImpl::ConvertAttributes( |
| + attributes, &in_process_attribs); |
| + in_process_attribs.lose_context_when_out_of_memory = 1; |
| + |
| + scoped_ptr<gpu::GLInProcessContext> context( |
| + gpu::GLInProcessContext::Create(service, |
| + surface, |
| + surface->IsOffscreen(), |
| + gfx::kNullAcceleratedWidget, |
| + surface->GetSize(), |
| + share_context, |
| + false /* share_resources */, |
|
mkosiba (inactive)
2014/05/19 20:01:16
you say share resources in line 46, but not here.
boliu
2014/05/19 23:13:01
Yes that's correct and not a bug...that's just how
|
| + in_process_attribs, |
| + gpu_preference)); |
| + DCHECK(context.get()); |
| + |
| + return webkit::gpu::ContextProviderInProcess::Create( |
| + WebGraphicsContext3DInProcessCommandBufferImpl::WrapContext( |
| + context.Pass(), attributes), |
| + "Parent-Compositor"); |
| +} |
| + |
| +} // namespace |
| + |
| HardwareRenderer::HardwareRenderer(SharedRendererState* state) |
| : shared_renderer_state_(state), |
| - last_egl_context_(eglGetCurrentContext()) { |
| + last_egl_context_(eglGetCurrentContext()), |
| + view_width_(-1), |
| + view_height_(-1), |
| + root_layer_(cc::Layer::Create()) { |
| DCHECK(last_egl_context_); |
| + root_layer_->SetIsDrawable(false); |
| + |
| gl_surface_ = new AwGLSurface; |
| - bool success = |
| - shared_renderer_state_->GetCompositor()-> |
| - InitializeHwDraw(gl_surface_); |
| - DCHECK(success); |
| + |
| + cc::LayerTreeSettings settings; |
| + |
| + // Copied. |
|
mkosiba (inactive)
2014/05/19 20:01:16
from?
|
| + settings.refresh_rate = 60.0; |
| + settings.impl_side_painting = false; |
| + settings.allow_antialiasing = false; |
| + settings.calculate_top_controls_position = false; |
| + settings.top_controls_height = 0.f; |
| + settings.highp_threshold_min = 2048; |
| + |
| + // Android WebView uses system scrollbars, so make ours invisible. |
| + settings.scrollbar_animator = cc::LayerTreeSettings::NoAnimator; |
| + settings.solid_color_scrollbar_color = SK_ColorTRANSPARENT; |
| + |
| + // Webview does not own the surface so should not clear it. |
| + settings.should_clear_root_render_pass = false; |
| + |
| + layer_tree_host_ = |
| + cc::LayerTreeHost::CreateSingleThreaded(this, this, NULL, settings); |
| + layer_tree_host_->SetRootLayer(root_layer_); |
| + layer_tree_host_->SetLayerTreeHostClientReady(); |
| + |
| + scoped_refptr<cc::ContextProvider> context_provider = |
| + CreateContext(gl_surface_, |
| + DeferredGpuCommandService::GetInstance(), |
| + shared_renderer_state_->GetSharedContext()); |
| + output_surface_holder_.reset(new ParentOutputSurface(context_provider)); |
| + output_surface_ = output_surface_holder_->GetWeakPtr(); |
| } |
| HardwareRenderer::~HardwareRenderer() { |
| - shared_renderer_state_->GetCompositor()->ReleaseHwDraw(); |
| - gl_surface_ = NULL; |
| + layer_tree_host_->SetRootLayer(NULL); |
| + layer_tree_host_.reset(); |
| + root_layer_->RemoveAllChildren(); |
| + |
| + // Order is important. |
|
mkosiba (inactive)
2014/05/19 20:01:16
..because one references the other I assume?
boliu
2014/05/19 23:13:01
Unfortunately these things are refcounted. Basical
|
| + layer_ = NULL; |
| + frame_provider_ = NULL; |
| + if (resource_collection_.get()) { |
| +#if DCHECK_IS_ON |
| + // Check collection is empty. |
| + cc::ReturnedResourceArray returned_resources; |
| + resource_collection_->TakeUnusedResourcesForChildCompositor( |
| + &returned_resources); |
| + DCHECK(returned_resources.empty()); |
| +#endif // DCHECK_IS_ON |
| + |
| + resource_collection_->SetClient(NULL); |
| + } |
| } |
| bool HardwareRenderer::DrawGL(bool stencil_enabled, |
| @@ -54,54 +151,76 @@ bool HardwareRenderer::DrawGL(bool stencil_enabled, |
| if (last_egl_context_ != current_context) |
| DLOG(WARNING) << "EGLContextChanged"; |
| - if (draw_info->mode != AwDrawGLInfo::kModeDraw) |
| - return false; |
| - |
| - // Should only need to access SharedRendererState in kModeDraw and kModeSync. |
| - const DrawGLInput input = shared_renderer_state_->GetDrawGLInput(); |
| - SetCompositorMemoryPolicy(); |
| + scoped_ptr<DrawGLInput> input = shared_renderer_state_->PassDrawGLInput(); |
| + if (!resource_collection_.get()) { |
| + resource_collection_ = new cc::DelegatedFrameResourceCollection; |
| + resource_collection_->SetClient(this); |
| + } |
| - gl_surface_->SetBackingFrameBufferObject(framebuffer_binding_ext); |
| + if (input.get()) { |
| + DCHECK(!input->frame.gl_frame_data); |
| + DCHECK(!input->frame.software_frame_data); |
| + |
| + bool size_changed = |
| + input->width != view_width_ || input->height != view_height_; |
| + view_width_ = input->width; |
| + view_height_ = input->height; |
| + scroll_offset_ = input->scroll_offset; |
| + |
| + if (!frame_provider_ || size_changed) { |
| + if (layer_) { |
| + layer_->RemoveFromParent(); |
| + } |
| + |
| + frame_provider_ = new cc::DelegatedFrameProvider( |
| + resource_collection_.get(), input->frame.delegated_frame_data.Pass()); |
| + |
| + layer_ = cc::DelegatedRendererLayer::Create(frame_provider_); |
| + layer_->SetBounds(gfx::Size(view_width_, view_height_)); |
| + layer_->SetIsDrawable(true); |
| + layer_->SetAnchorPoint(gfx::PointF(0.f, 0.f)); |
| + |
| + root_layer_->AddChild(layer_); |
| + } else { |
| + frame_provider_->SetFrameData(input->frame.delegated_frame_data.Pass()); |
| + } |
| + } |
| - gfx::Transform transform; |
| - transform.matrix().setColMajorf(draw_info->transform); |
| - transform.Translate(input.scroll_offset.x(), input.scroll_offset.y()); |
| + gfx::Size viewport(draw_info->width, draw_info->height); |
| + layer_tree_host_->SetViewportSize(viewport); |
| gfx::Rect clip_rect(draw_info->clip_left, |
| draw_info->clip_top, |
| draw_info->clip_right - draw_info->clip_left, |
| draw_info->clip_bottom - draw_info->clip_top); |
| - |
| - gfx::Rect viewport(draw_info->width, draw_info->height); |
| - if (!draw_info->is_layer) { |
| - gfx::RectF view_rect(input.width, input.height); |
| - transform.TransformRect(&view_rect); |
| - viewport.Intersect(gfx::ToEnclosingRect(view_rect)); |
| + DCHECK(output_surface_); |
| + if (output_surface_) { |
| + output_surface_->SetDrawConstraints(viewport, clip_rect); |
| } |
| + gfx::Transform transform(gfx::Transform::kSkipInitialization); |
| + transform.matrix().setColMajorf(draw_info->transform); |
| + transform.Translate(scroll_offset_.x(), scroll_offset_.y()); |
| + layer_->SetTransform(transform); |
| - bool did_draw = shared_renderer_state_->GetCompositor()->DemandDrawHw( |
| - gfx::Size(draw_info->width, draw_info->height), |
| - transform, |
| - viewport, |
| - clip_rect, |
| - stencil_enabled); |
| + gl_surface_->SetBackingFrameBufferObject(framebuffer_binding_ext); |
|
mkosiba (inactive)
2014/05/19 20:01:16
could you please explain a bit about what is frame
boliu
2014/05/19 23:13:01
Well, frameworks is. That's what happens when we a
|
| + layer_tree_host_->Composite(gfx::FrameTime::Now()); |
| gl_surface_->ResetBackingFrameBufferObject(); |
| - if (did_draw) { |
| - result->frame_id = input.frame_id; |
| - result->clip_contains_visible_rect = |
| - clip_rect.Contains(input.global_visible_rect); |
| - } |
| - return did_draw; |
| + return true; |
| } |
| -void HardwareRenderer::SetCompositorMemoryPolicy() { |
| - if (shared_renderer_state_->IsMemoryPolicyDirty()) { |
| - content::SynchronousCompositorMemoryPolicy policy = |
| - shared_renderer_state_->GetMemoryPolicy(); |
| - // Memory policy is set by BrowserViewRenderer on UI thread. |
| - shared_renderer_state_->GetCompositor()->SetMemoryPolicy(policy); |
| - shared_renderer_state_->SetMemoryPolicyDirty(false); |
| - } |
| +scoped_ptr<cc::OutputSurface> HardwareRenderer::CreateOutputSurface( |
| + bool fallback) { |
| + // Android webview does not lose output surface. |
| + DCHECK(!fallback); |
| + DCHECK(output_surface_holder_.get()); |
| + return output_surface_holder_.PassAs<cc::OutputSurface>(); |
| +} |
| + |
| +void HardwareRenderer::UnusedResourcesAreAvailable() { |
| + cc::ReturnedResourceArray returned_resources; |
| + resource_collection_->TakeUnusedResourcesForChildCompositor( |
| + &returned_resources); |
| + shared_renderer_state_->InsertReturnedResources(returned_resources); |
| } |
| } // namespace android_webview |