blob: 78f1643b1ca34da8d5afce4b3c4f8979969d6d71 [file] [log] [blame]
[email protected]bffc8302014-01-23 20:52:161// Copyright 2014 The Chromium Authors. All rights reserved.
[email protected]0f21e8582013-01-11 11:06:562// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]bffc8302014-01-23 20:52:165#include "content/renderer/child_frame_compositing_helper.h"
[email protected]0f21e8582013-01-11 11:06:566
dcheng07945f632015-12-26 07:59:327#include <utility>
8
[email protected]38564622014-08-19 02:47:189#include "cc/blink/web_layer_impl.h"
lfgcccffbe2016-03-10 00:05:4610#include "cc/layers/picture_image_layer.h"
[email protected]cc3cfaa2013-03-18 09:05:5211#include "cc/layers/solid_color_layer.h"
kenrbfc7c02c92015-05-29 22:20:5812#include "cc/layers/surface_layer.h"
[email protected]7f0d825f2013-03-18 07:24:3013#include "cc/output/context_provider.h"
[email protected]73405fb2013-12-11 04:59:3714#include "cc/output/copy_output_request.h"
15#include "cc/output/copy_output_result.h"
vmpstr55c7657ca2017-04-29 00:46:4816#include "cc/paint/paint_image.h"
[email protected]9260757f2013-09-17 01:24:1617#include "cc/resources/single_release_callback.h"
samans72b2a282016-12-17 02:44:1518#include "cc/surfaces/sequence_surface_reference_factory.h"
jbauman38c178eaa2015-06-04 04:24:5419#include "content/child/thread_safe_sender.h"
[email protected]703dd662013-03-05 07:37:4220#include "content/common/browser_plugin/browser_plugin_messages.h"
oshima9000e422016-01-27 03:05:3621#include "content/common/content_switches_internal.h"
[email protected]95d31822014-01-03 22:21:5522#include "content/common/frame_messages.h"
lfgcccffbe2016-03-10 00:05:4623#include "content/public/common/content_client.h"
24#include "content/public/renderer/content_renderer_client.h"
[email protected]94224ba62014-02-04 00:25:2425#include "content/renderer/browser_plugin/browser_plugin.h"
[email protected]0d25cb62013-01-21 15:42:2126#include "content/renderer/browser_plugin/browser_plugin_manager.h"
[email protected]bffc8302014-01-23 20:52:1627#include "content/renderer/render_frame_impl.h"
[email protected]e3244ed2014-06-20 20:04:2728#include "content/renderer/render_frame_proxy.h"
[email protected]0f21e8582013-01-11 11:06:5629#include "content/renderer/render_thread_impl.h"
sadrul85cc5d82016-12-20 03:37:4130#include "services/ui/public/cpp/gpu/context_provider_command_buffer.h"
[email protected]73405fb2013-12-11 04:59:3731#include "skia/ext/image_operations.h"
[email protected]2255a9332013-06-17 05:12:3132#include "third_party/WebKit/public/web/WebPluginContainer.h"
dcheng5cf543012016-11-24 17:13:3733#include "third_party/WebKit/public/web/WebRemoteFrame.h"
[email protected]7f0d825f2013-03-18 07:24:3034#include "third_party/khronos/GLES2/gl2.h"
lfgcccffbe2016-03-10 00:05:4635#include "third_party/skia/include/core/SkBitmap.h"
36#include "third_party/skia/include/core/SkImage.h"
37#include "ui/gfx/geometry/point_f.h"
tfarinaebe974f02015-01-03 04:25:3238#include "ui/gfx/geometry/size_conversions.h"
[email protected]73405fb2013-12-11 04:59:3739#include "ui/gfx/skia_util.h"
[email protected]0f21e8582013-01-11 11:06:5640
41namespace content {
42
samans72b2a282016-12-17 02:44:1543namespace {
44
45class IframeSurfaceReferenceFactory
46 : public cc::SequenceSurfaceReferenceFactory {
47 public:
48 IframeSurfaceReferenceFactory(scoped_refptr<ThreadSafeSender> sender,
49 int routing_id)
50 : sender_(std::move(sender)), routing_id_(routing_id) {}
51
52 private:
53 ~IframeSurfaceReferenceFactory() override = default;
54
55 // cc::SequenceSurfaceReferenceFactory implementation:
56 void RequireSequence(const cc::SurfaceId& surface_id,
57 const cc::SurfaceSequence& sequence) const override {
58 sender_->Send(
59 new FrameHostMsg_RequireSequence(routing_id_, surface_id, sequence));
60 }
61
62 void SatisfySequence(const cc::SurfaceSequence& sequence) const override {
63 sender_->Send(new FrameHostMsg_SatisfySequence(routing_id_, sequence));
64 }
65
66 const scoped_refptr<ThreadSafeSender> sender_;
67 const int routing_id_;
68
69 DISALLOW_COPY_AND_ASSIGN(IframeSurfaceReferenceFactory);
70};
71
72class BrowserPluginSurfaceReferenceFactory
73 : public cc::SequenceSurfaceReferenceFactory {
74 public:
75 BrowserPluginSurfaceReferenceFactory(scoped_refptr<ThreadSafeSender> sender,
76 int routing_id,
77 int browser_plugin_instance_id)
78 : sender_(std::move(sender)),
79 routing_id_(routing_id),
80 browser_plugin_instance_id_(browser_plugin_instance_id) {}
81
82 private:
83 ~BrowserPluginSurfaceReferenceFactory() override = default;
84
85 // cc::SequenceSurfaceRefrenceFactory implementation:
86 void SatisfySequence(const cc::SurfaceSequence& seq) const override {
87 sender_->Send(new BrowserPluginHostMsg_SatisfySequence(
88 routing_id_, browser_plugin_instance_id_, seq));
89 }
90
91 void RequireSequence(const cc::SurfaceId& surface_id,
92 const cc::SurfaceSequence& sequence) const override {
93 sender_->Send(new BrowserPluginHostMsg_RequireSequence(
94 routing_id_, browser_plugin_instance_id_, surface_id, sequence));
95 }
96
97 const scoped_refptr<ThreadSafeSender> sender_;
98 const int routing_id_;
99 const int browser_plugin_instance_id_;
100
101 DISALLOW_COPY_AND_ASSIGN(BrowserPluginSurfaceReferenceFactory);
102};
103
104} // namespace
105
[email protected]bffc8302014-01-23 20:52:16106ChildFrameCompositingHelper*
[email protected]c092f5c2014-07-18 01:34:33107ChildFrameCompositingHelper::CreateForBrowserPlugin(
[email protected]94224ba62014-02-04 00:25:24108 const base::WeakPtr<BrowserPlugin>& browser_plugin) {
[email protected]bffc8302014-01-23 20:52:16109 return new ChildFrameCompositingHelper(
kenrbfc7c02c92015-05-29 22:20:58110 browser_plugin, nullptr, nullptr,
111 browser_plugin->render_frame_routing_id());
[email protected]bffc8302014-01-23 20:52:16112}
113
114ChildFrameCompositingHelper*
[email protected]c092f5c2014-07-18 01:34:33115ChildFrameCompositingHelper::CreateForRenderFrameProxy(
116 RenderFrameProxy* render_frame_proxy) {
lfgfd437a272015-11-24 21:24:53117 return new ChildFrameCompositingHelper(
118 base::WeakPtr<BrowserPlugin>(), render_frame_proxy->web_frame(),
119 render_frame_proxy, render_frame_proxy->routing_id());
[email protected]bffc8302014-01-23 20:52:16120}
121
122ChildFrameCompositingHelper::ChildFrameCompositingHelper(
[email protected]94224ba62014-02-04 00:25:24123 const base::WeakPtr<BrowserPlugin>& browser_plugin,
dcheng5cf543012016-11-24 17:13:37124 blink::WebRemoteFrame* frame,
[email protected]e3244ed2014-06-20 20:04:27125 RenderFrameProxy* render_frame_proxy,
[email protected]0f21e8582013-01-11 11:06:56126 int host_routing_id)
[email protected]94224ba62014-02-04 00:25:24127 : host_routing_id_(host_routing_id),
[email protected]94224ba62014-02-04 00:25:24128 browser_plugin_(browser_plugin),
[email protected]e3244ed2014-06-20 20:04:27129 render_frame_proxy_(render_frame_proxy),
samans72b2a282016-12-17 02:44:15130 frame_(frame) {
131 scoped_refptr<ThreadSafeSender> sender(
132 RenderThreadImpl::current()->thread_safe_sender());
133 if (render_frame_proxy_) {
134 surface_reference_factory_ =
135 new IframeSurfaceReferenceFactory(sender, host_routing_id_);
136 } else {
137 surface_reference_factory_ = new BrowserPluginSurfaceReferenceFactory(
138 sender, host_routing_id_,
139 browser_plugin_->browser_plugin_instance_id());
140 }
141}
[email protected]bffc8302014-01-23 20:52:16142
lfga7d368e2015-02-03 23:01:37143ChildFrameCompositingHelper::~ChildFrameCompositingHelper() {
lfga7d368e2015-02-03 23:01:37144}
[email protected]bffc8302014-01-23 20:52:16145
[email protected]94224ba62014-02-04 00:25:24146blink::WebPluginContainer* ChildFrameCompositingHelper::GetContainer() {
147 if (!browser_plugin_)
kenrbfc7c02c92015-05-29 22:20:58148 return nullptr;
[email protected]94224ba62014-02-04 00:25:24149
Blink Reformat1c4d759e2017-04-09 16:34:54150 return browser_plugin_->Container();
[email protected]94224ba62014-02-04 00:25:24151}
152
vmpstre87ffcaa2016-08-23 21:01:14153void ChildFrameCompositingHelper::UpdateWebLayer(
154 std::unique_ptr<blink::WebLayer> layer) {
[email protected]94224ba62014-02-04 00:25:24155 if (GetContainer()) {
Blink Reformat1c4d759e2017-04-09 16:34:54156 GetContainer()->SetWebLayer(layer.get());
[email protected]94224ba62014-02-04 00:25:24157 } else if (frame_) {
Blink Reformat1c4d759e2017-04-09 16:34:54158 frame_->SetWebLayer(layer.get());
[email protected]bffc8302014-01-23 20:52:16159 }
vmpstre87ffcaa2016-08-23 21:01:14160 web_layer_ = std::move(layer);
[email protected]0f21e8582013-01-11 11:06:56161}
162
[email protected]bffc8302014-01-23 20:52:16163void ChildFrameCompositingHelper::CheckSizeAndAdjustLayerProperties(
[email protected]f5b4b0f2013-04-02 18:16:28164 const gfx::Size& new_size,
165 float device_scale_factor,
166 cc::Layer* layer) {
167 if (buffer_size_ != new_size) {
168 buffer_size_ = new_size;
169 // The container size is in DIP, so is the layer size.
170 // Buffer size is in physical pixels, so we need to adjust
171 // it by the device scale factor.
danakjddaec912015-09-25 19:38:40172 gfx::Size device_scale_adjusted_size =
173 gfx::ScaleToFlooredSize(buffer_size_, 1.0f / device_scale_factor);
[email protected]f5b4b0f2013-04-02 18:16:28174 layer->SetBounds(device_scale_adjusted_size);
175 }
176}
177
[email protected]bffc8302014-01-23 20:52:16178void ChildFrameCompositingHelper::OnContainerDestroy() {
lfgfd437a272015-11-24 21:24:53179 UpdateWebLayer(nullptr);
[email protected]0d25cb62013-01-21 15:42:21180}
181
[email protected]f49722f2014-01-30 17:54:50182void ChildFrameCompositingHelper::ChildFrameGone() {
lfgfd437a272015-11-24 21:24:53183 scoped_refptr<cc::SolidColorLayer> crashed_layer =
loyso0940d412016-03-14 01:30:31184 cc::SolidColorLayer::Create();
lfgfd437a272015-11-24 21:24:53185 crashed_layer->SetMasksToBounds(true);
lfgcccffbe2016-03-10 00:05:46186 crashed_layer->SetBackgroundColor(SK_ColorBLACK);
187
188 if (web_layer_) {
189 SkBitmap* sad_bitmap =
190 GetContentClient()->renderer()->GetSadWebViewBitmap();
Blink Reformat1c4d759e2017-04-09 16:34:54191 if (sad_bitmap && web_layer_->Bounds().width > sad_bitmap->width() &&
192 web_layer_->Bounds().height > sad_bitmap->height()) {
lfgcccffbe2016-03-10 00:05:46193 scoped_refptr<cc::PictureImageLayer> sad_layer =
loyso0940d412016-03-14 01:30:31194 cc::PictureImageLayer::Create();
vmpstr55c7657ca2017-04-29 00:46:48195 sad_layer->SetImage(cc::PaintImage(SkImage::MakeFromBitmap(*sad_bitmap)));
lfgcccffbe2016-03-10 00:05:46196 sad_layer->SetBounds(
197 gfx::Size(sad_bitmap->width(), sad_bitmap->height()));
198 sad_layer->SetPosition(gfx::PointF(
Blink Reformat1c4d759e2017-04-09 16:34:54199 (web_layer_->Bounds().width - sad_bitmap->width()) / 2,
200 (web_layer_->Bounds().height - sad_bitmap->height()) / 2));
lfgcccffbe2016-03-10 00:05:46201 sad_layer->SetIsDrawable(true);
202
203 crashed_layer->AddChild(sad_layer);
204 }
205 }
206
vmpstre87ffcaa2016-08-23 21:01:14207 std::unique_ptr<blink::WebLayer> layer(
208 new cc_blink::WebLayerImpl(crashed_layer));
209 UpdateWebLayer(std::move(layer));
[email protected]f49722f2014-01-30 17:54:50210}
211
kenrbfc7c02c92015-05-29 22:20:58212void ChildFrameCompositingHelper::OnSetSurface(
fsamuel96795522017-01-04 02:41:32213 const cc::SurfaceInfo& surface_info,
kenrbfc7c02c92015-05-29 22:20:58214 const cc::SurfaceSequence& sequence) {
fsamuel96795522017-01-04 02:41:32215 float scale_factor = surface_info.device_scale_factor();
216 surface_id_ = surface_info.id();
lfgfd437a272015-11-24 21:24:53217 scoped_refptr<cc::SurfaceLayer> surface_layer =
samans72b2a282016-12-17 02:44:15218 cc::SurfaceLayer::Create(surface_reference_factory_);
oshima9000e422016-01-27 03:05:36219 // TODO(oshima): This is a stopgap fix so that the compositor does not
220 // scaledown the content when 2x frame data is added to 1x parent frame data.
221 // Fix this in cc/.
222 if (IsUseZoomForDSFEnabled())
223 scale_factor = 1.0f;
fsamuel96795522017-01-04 02:41:32224
fsamuel1d3252c2017-02-15 20:56:37225 surface_layer->SetPrimarySurfaceInfo(cc::SurfaceInfo(
226 surface_info.id(), scale_factor, surface_info.size_in_pixels()));
lfg042482c2016-01-21 03:53:55227 surface_layer->SetMasksToBounds(true);
vmpstre87ffcaa2016-08-23 21:01:14228 std::unique_ptr<cc_blink::WebLayerImpl> layer(
229 new cc_blink::WebLayerImpl(surface_layer));
lfg04c6bd602016-07-20 17:02:52230 // TODO(lfg): Investigate if it's possible to propagate the information about
231 // the child surface's opacity. https://crbug.com/629851.
Blink Reformat1c4d759e2017-04-09 16:34:54232 layer->SetOpaque(false);
lfg04c6bd602016-07-20 17:02:52233 layer->SetContentsOpaqueIsFixed(true);
vmpstre87ffcaa2016-08-23 21:01:14234 UpdateWebLayer(std::move(layer));
kenrbfc7c02c92015-05-29 22:20:58235
kenrbfc7c02c92015-05-29 22:20:58236 UpdateVisibility(true);
kenrbfc7c02c92015-05-29 22:20:58237
238 // The RWHV creates a destruction dependency on the surface that needs to be
wjmaclean53032adf2015-06-15 16:49:22239 // satisfied. Note: render_frame_proxy_ is null in the case our client is a
240 // BrowserPlugin; in this case the BrowserPlugin sends its own SatisfySequence
241 // message.
242 if (render_frame_proxy_) {
243 render_frame_proxy_->Send(
244 new FrameHostMsg_SatisfySequence(host_routing_id_, sequence));
245 } else if (browser_plugin_.get()) {
246 browser_plugin_->SendSatisfySequence(sequence);
247 }
kenrbfc7c02c92015-05-29 22:20:58248
lfgfd437a272015-11-24 21:24:53249 CheckSizeAndAdjustLayerProperties(
fsamuel96795522017-01-04 02:41:32250 surface_info.size_in_pixels(), surface_info.device_scale_factor(),
lfgfd437a272015-11-24 21:24:53251 static_cast<cc_blink::WebLayerImpl*>(web_layer_.get())->layer());
kenrbfc7c02c92015-05-29 22:20:58252}
253
[email protected]bffc8302014-01-23 20:52:16254void ChildFrameCompositingHelper::UpdateVisibility(bool visible) {
lfgfd437a272015-11-24 21:24:53255 if (web_layer_)
Blink Reformat1c4d759e2017-04-09 16:34:54256 web_layer_->SetDrawsContent(visible);
[email protected]69b79122013-02-14 19:16:45257}
258
[email protected]0f21e8582013-01-11 11:06:56259} // namespace content