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..afce940ee7d372ab98d1a894a6962dec576f6783 100644 |
--- a/android_webview/browser/hardware_renderer.cc |
+++ b/android_webview/browser/hardware_renderer.cc |
@@ -5,35 +5,94 @@ |
#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 "cc/output/compositor_frame.h" |
+#include "cc/output/output_surface.h" |
+#include "cc/layers/delegated_frame_provider.h" |
+#include "cc/layers/delegated_renderer_layer.h" |
+#include "cc/layers/layer.h" |
+#include "cc/trees/layer_tree_host.h" |
+#include "cc/trees/layer_tree_settings.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 "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" |
+ |
+// TODO(boliu): Layering violation. |
+#include "content/browser/android/in_process/synchronous_compositor_factory_impl.h" |
namespace android_webview { |
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. |
+ 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 = |
+ content::SynchronousCompositor::GetFactory() |
+ ->CreateOnscreenContextProviderForCompositorThread(gl_surface_); |
+ output_surface_holder_.reset(new ParentOutputSurface(context_provider)); |
+ output_surface_ = output_surface_holder_->GetWeakPtr(); |
} |
HardwareRenderer::~HardwareRenderer() { |
- shared_renderer_state_->GetCompositor()->ReleaseHwDraw(); |
- gl_surface_ = NULL; |
+ scoped_ptr<DrawGLInput> input = shared_renderer_state_->PassDrawGLInput(); |
+ if (input.get()) { |
+ shared_renderer_state_->ReturnResources( |
+ input->frame.delegated_frame_data->resource_list); |
+ } |
+ |
+ layer_tree_host_->SetRootLayer(NULL); |
+ layer_tree_host_.reset(); |
+ root_layer_->RemoveAllChildren(); |
+ |
+ layer_ = NULL; |
+ frame_provider_ = NULL; |
+ if (resource_collection_.get()) { |
+ resource_collection_->SetClient(NULL); |
+ // TODO(boliu): Check collection is empty. |
+ } |
+ resource_collection_ = NULL; |
} |
bool HardwareRenderer::DrawGL(bool stencil_enabled, |
@@ -57,51 +116,75 @@ bool HardwareRenderer::DrawGL(bool stencil_enabled, |
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); |
- gfx::Transform transform; |
- transform.matrix().setColMajorf(draw_info->transform); |
- transform.Translate(input.scroll_offset.x(), input.scroll_offset.y()); |
+ 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()); |
+ } |
+ } |
+ |
+ // TODO(boliu): Clip |
+ 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)); |
+ 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); |
+ 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); |
+ // TODO(boliu): Notify child? |
} |
} // namespace android_webview |