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.
4
5 #include "mojo/services/html_viewer/weblayertreeview_impl.h"
6
7 #include "base/message_loop/message_loop_proxy.h"
8 #include "cc/blink/web_layer_impl.h"
9 #include "cc/layers/layer.h"
10 #include "cc/output/begin_frame_args.h"
11 #include "cc/trees/layer_tree_host.h"
12 #include "mojo/cc/context_provider_mojo.h"
13 #include "mojo/cc/output_surface_mojo.h"
14 #include "mojo/services/public/cpp/surfaces/surfaces_type_converters.h"
15 #include "mojo/services/public/cpp/view_manager/view.h"
16 #include "third_party/WebKit/public/web/WebWidget.h"
17
18 namespace mojo {
19
WebLayerTreeViewImpl(scoped_refptr<base::MessageLoopProxy> compositor_message_loop_proxy,SurfacesServicePtr surfaces_service,GpuPtr gpu_service)20 WebLayerTreeViewImpl::WebLayerTreeViewImpl(
21 scoped_refptr<base::MessageLoopProxy> compositor_message_loop_proxy,
22 SurfacesServicePtr surfaces_service,
23 GpuPtr gpu_service)
24 : widget_(NULL),
25 view_(NULL),
26 surfaces_service_(surfaces_service.Pass()),
27 gpu_service_(gpu_service.Pass()),
28 main_thread_compositor_task_runner_(base::MessageLoopProxy::current()),
29 weak_factory_(this) {
30 main_thread_bound_weak_ptr_ = weak_factory_.GetWeakPtr();
31 surfaces_service_->CreateSurfaceConnection(
32 base::Bind(&WebLayerTreeViewImpl::OnSurfaceConnectionCreated,
33 main_thread_bound_weak_ptr_));
34
35 cc::LayerTreeSettings settings;
36
37 // For web contents, layer transforms should scale up the contents of layers
38 // to keep content always crisp when possible.
39 settings.layer_transforms_should_scale_layer_contents = true;
40
41 cc::SharedBitmapManager* shared_bitmap_manager = NULL;
42
43 layer_tree_host_ =
44 cc::LayerTreeHost::CreateThreaded(this,
45 shared_bitmap_manager,
46 settings,
47 base::MessageLoopProxy::current(),
48 compositor_message_loop_proxy);
49 DCHECK(layer_tree_host_);
50 }
51
~WebLayerTreeViewImpl()52 WebLayerTreeViewImpl::~WebLayerTreeViewImpl() {
53 }
54
WillBeginMainFrame(int frame_id)55 void WebLayerTreeViewImpl::WillBeginMainFrame(int frame_id) {
56 }
57
DidBeginMainFrame()58 void WebLayerTreeViewImpl::DidBeginMainFrame() {
59 }
60
BeginMainFrame(const cc::BeginFrameArgs & args)61 void WebLayerTreeViewImpl::BeginMainFrame(const cc::BeginFrameArgs& args) {
62 VLOG(2) << "WebLayerTreeViewImpl::BeginMainFrame";
63 double frame_time_sec = (args.frame_time - base::TimeTicks()).InSecondsF();
64 double deadline_sec = (args.deadline - base::TimeTicks()).InSecondsF();
65 double interval_sec = args.interval.InSecondsF();
66 blink::WebBeginFrameArgs web_begin_frame_args(
67 frame_time_sec, deadline_sec, interval_sec);
68 widget_->beginFrame(web_begin_frame_args);
69 }
70
Layout()71 void WebLayerTreeViewImpl::Layout() {
72 widget_->layout();
73 }
74
ApplyViewportDeltas(const gfx::Vector2d & scroll_delta,float page_scale,float top_controls_delta)75 void WebLayerTreeViewImpl::ApplyViewportDeltas(
76 const gfx::Vector2d& scroll_delta,
77 float page_scale,
78 float top_controls_delta) {
79 widget_->applyViewportDeltas(scroll_delta, page_scale, top_controls_delta);
80 }
81
RequestNewOutputSurface(bool fallback)82 void WebLayerTreeViewImpl::RequestNewOutputSurface(bool fallback) {
83 layer_tree_host_->SetOutputSurface(output_surface_.Pass());
84 }
85
DidInitializeOutputSurface()86 void WebLayerTreeViewImpl::DidInitializeOutputSurface() {
87 }
88
WillCommit()89 void WebLayerTreeViewImpl::WillCommit() {
90 }
91
DidCommit()92 void WebLayerTreeViewImpl::DidCommit() {
93 widget_->didCommitFrameToCompositor();
94 }
95
DidCommitAndDrawFrame()96 void WebLayerTreeViewImpl::DidCommitAndDrawFrame() {
97 }
98
DidCompleteSwapBuffers()99 void WebLayerTreeViewImpl::DidCompleteSwapBuffers() {
100 }
101
setSurfaceReady()102 void WebLayerTreeViewImpl::setSurfaceReady() {
103 }
104
setRootLayer(const blink::WebLayer & layer)105 void WebLayerTreeViewImpl::setRootLayer(const blink::WebLayer& layer) {
106 layer_tree_host_->SetRootLayer(
107 static_cast<const cc_blink::WebLayerImpl*>(&layer)->layer());
108 }
109
clearRootLayer()110 void WebLayerTreeViewImpl::clearRootLayer() {
111 layer_tree_host_->SetRootLayer(scoped_refptr<cc::Layer>());
112 }
113
setViewportSize(const blink::WebSize & device_viewport_size)114 void WebLayerTreeViewImpl::setViewportSize(
115 const blink::WebSize& device_viewport_size) {
116 layer_tree_host_->SetViewportSize(device_viewport_size);
117 }
118
deviceViewportSize() const119 blink::WebSize WebLayerTreeViewImpl::deviceViewportSize() const {
120 return layer_tree_host_->device_viewport_size();
121 }
122
setDeviceScaleFactor(float device_scale_factor)123 void WebLayerTreeViewImpl::setDeviceScaleFactor(float device_scale_factor) {
124 layer_tree_host_->SetDeviceScaleFactor(device_scale_factor);
125 }
126
deviceScaleFactor() const127 float WebLayerTreeViewImpl::deviceScaleFactor() const {
128 return layer_tree_host_->device_scale_factor();
129 }
130
setBackgroundColor(blink::WebColor color)131 void WebLayerTreeViewImpl::setBackgroundColor(blink::WebColor color) {
132 layer_tree_host_->set_background_color(color);
133 }
134
setHasTransparentBackground(bool has_transparent_background)135 void WebLayerTreeViewImpl::setHasTransparentBackground(
136 bool has_transparent_background) {
137 layer_tree_host_->set_has_transparent_background(has_transparent_background);
138 }
139
setOverhangBitmap(const SkBitmap & bitmap)140 void WebLayerTreeViewImpl::setOverhangBitmap(const SkBitmap& bitmap) {
141 layer_tree_host_->SetOverhangBitmap(bitmap);
142 }
143
setVisible(bool visible)144 void WebLayerTreeViewImpl::setVisible(bool visible) {
145 layer_tree_host_->SetVisible(visible);
146 }
147
setPageScaleFactorAndLimits(float page_scale_factor,float minimum,float maximum)148 void WebLayerTreeViewImpl::setPageScaleFactorAndLimits(float page_scale_factor,
149 float minimum,
150 float maximum) {
151 layer_tree_host_->SetPageScaleFactorAndLimits(
152 page_scale_factor, minimum, maximum);
153 }
154
registerForAnimations(blink::WebLayer * layer)155 void WebLayerTreeViewImpl::registerForAnimations(blink::WebLayer* layer) {
156 cc::Layer* cc_layer = static_cast<cc_blink::WebLayerImpl*>(layer)->layer();
157 cc_layer->layer_animation_controller()->SetAnimationRegistrar(
158 layer_tree_host_->animation_registrar());
159 }
160
registerViewportLayers(const blink::WebLayer * pageScaleLayer,const blink::WebLayer * innerViewportScrollLayer,const blink::WebLayer * outerViewportScrollLayer)161 void WebLayerTreeViewImpl::registerViewportLayers(
162 const blink::WebLayer* pageScaleLayer,
163 const blink::WebLayer* innerViewportScrollLayer,
164 const blink::WebLayer* outerViewportScrollLayer) {
165 layer_tree_host_->RegisterViewportLayers(
166 static_cast<const cc_blink::WebLayerImpl*>(pageScaleLayer)->layer(),
167 static_cast<const cc_blink::WebLayerImpl*>(innerViewportScrollLayer)
168 ->layer(),
169 // The outer viewport layer will only exist when using pinch virtual
170 // viewports.
171 outerViewportScrollLayer ? static_cast<const cc_blink::WebLayerImpl*>(
172 outerViewportScrollLayer)->layer()
173 : NULL);
174 }
175
clearViewportLayers()176 void WebLayerTreeViewImpl::clearViewportLayers() {
177 layer_tree_host_->RegisterViewportLayers(scoped_refptr<cc::Layer>(),
178 scoped_refptr<cc::Layer>(),
179 scoped_refptr<cc::Layer>());
180 }
181
startPageScaleAnimation(const blink::WebPoint & destination,bool use_anchor,float new_page_scale,double duration_sec)182 void WebLayerTreeViewImpl::startPageScaleAnimation(
183 const blink::WebPoint& destination,
184 bool use_anchor,
185 float new_page_scale,
186 double duration_sec) {
187 base::TimeDelta duration = base::TimeDelta::FromMicroseconds(
188 duration_sec * base::Time::kMicrosecondsPerSecond);
189 layer_tree_host_->StartPageScaleAnimation(
190 gfx::Vector2d(destination.x, destination.y),
191 use_anchor,
192 new_page_scale,
193 duration);
194 }
195
setNeedsAnimate()196 void WebLayerTreeViewImpl::setNeedsAnimate() {
197 layer_tree_host_->SetNeedsAnimate();
198 }
199
commitRequested() const200 bool WebLayerTreeViewImpl::commitRequested() const {
201 return layer_tree_host_->CommitRequested();
202 }
203
finishAllRendering()204 void WebLayerTreeViewImpl::finishAllRendering() {
205 layer_tree_host_->FinishAllRendering();
206 }
207
OnSurfaceConnectionCreated(SurfacePtr surface,uint32_t id_namespace)208 void WebLayerTreeViewImpl::OnSurfaceConnectionCreated(SurfacePtr surface,
209 uint32_t id_namespace) {
210 CommandBufferPtr cb;
211 gpu_service_->CreateOffscreenGLES2Context(Get(&cb));
212 scoped_refptr<cc::ContextProvider> context_provider(
213 new ContextProviderMojo(cb.PassMessagePipe()));
214 output_surface_.reset(new OutputSurfaceMojo(
215 this, context_provider, surface.Pass(), id_namespace));
216 layer_tree_host_->SetLayerTreeHostClientReady();
217 }
218
DidCreateSurface(cc::SurfaceId id)219 void WebLayerTreeViewImpl::DidCreateSurface(cc::SurfaceId id) {
220 main_thread_compositor_task_runner_->PostTask(
221 FROM_HERE,
222 base::Bind(&WebLayerTreeViewImpl::DidCreateSurfaceOnMainThread,
223 main_thread_bound_weak_ptr_,
224 id));
225 }
226
DidCreateSurfaceOnMainThread(cc::SurfaceId id)227 void WebLayerTreeViewImpl::DidCreateSurfaceOnMainThread(cc::SurfaceId id) {
228 view_->SetSurfaceId(SurfaceId::From(id));
229 }
230
231 } // namespace mojo
232