blob: 279d17ae2f9ac022ed1549a1b4206d879cafafac [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"
[email protected]9260757f2013-09-17 01:24:1616#include "cc/resources/single_release_callback.h"
samans72b2a282016-12-17 02:44:1517#include "cc/surfaces/sequence_surface_reference_factory.h"
jbauman38c178eaa2015-06-04 04:24:5418#include "content/child/thread_safe_sender.h"
[email protected]703dd662013-03-05 07:37:4219#include "content/common/browser_plugin/browser_plugin_messages.h"
oshima9000e422016-01-27 03:05:3620#include "content/common/content_switches_internal.h"
[email protected]95d31822014-01-03 22:21:5521#include "content/common/frame_messages.h"
lfgcccffbe2016-03-10 00:05:4622#include "content/public/common/content_client.h"
23#include "content/public/renderer/content_renderer_client.h"
[email protected]94224ba62014-02-04 00:25:2424#include "content/renderer/browser_plugin/browser_plugin.h"
[email protected]0d25cb62013-01-21 15:42:2125#include "content/renderer/browser_plugin/browser_plugin_manager.h"
[email protected]bffc8302014-01-23 20:52:1626#include "content/renderer/render_frame_impl.h"
[email protected]e3244ed2014-06-20 20:04:2727#include "content/renderer/render_frame_proxy.h"
[email protected]0f21e8582013-01-11 11:06:5628#include "content/renderer/render_thread_impl.h"
sadrul85cc5d82016-12-20 03:37:4129#include "services/ui/public/cpp/gpu/context_provider_command_buffer.h"
[email protected]73405fb2013-12-11 04:59:3730#include "skia/ext/image_operations.h"
[email protected]2255a9332013-06-17 05:12:3131#include "third_party/WebKit/public/web/WebPluginContainer.h"
dcheng5cf543012016-11-24 17:13:3732#include "third_party/WebKit/public/web/WebRemoteFrame.h"
[email protected]7f0d825f2013-03-18 07:24:3033#include "third_party/khronos/GLES2/gl2.h"
lfgcccffbe2016-03-10 00:05:4634#include "third_party/skia/include/core/SkBitmap.h"
35#include "third_party/skia/include/core/SkImage.h"
36#include "ui/gfx/geometry/point_f.h"
tfarinaebe974f02015-01-03 04:25:3237#include "ui/gfx/geometry/size_conversions.h"
[email protected]73405fb2013-12-11 04:59:3738#include "ui/gfx/skia_util.h"
[email protected]0f21e8582013-01-11 11:06:5639
40namespace content {
41
samans72b2a282016-12-17 02:44:1542namespace {
43
44class IframeSurfaceReferenceFactory
45 : public cc::SequenceSurfaceReferenceFactory {
46 public:
47 IframeSurfaceReferenceFactory(scoped_refptr<ThreadSafeSender> sender,
48 int routing_id)
49 : sender_(std::move(sender)), routing_id_(routing_id) {}
50
51 private:
52 ~IframeSurfaceReferenceFactory() override = default;
53
54 // cc::SequenceSurfaceReferenceFactory implementation:
55 void RequireSequence(const cc::SurfaceId& surface_id,
56 const cc::SurfaceSequence& sequence) const override {
57 sender_->Send(
58 new FrameHostMsg_RequireSequence(routing_id_, surface_id, sequence));
59 }
60
61 void SatisfySequence(const cc::SurfaceSequence& sequence) const override {
62 sender_->Send(new FrameHostMsg_SatisfySequence(routing_id_, sequence));
63 }
64
65 const scoped_refptr<ThreadSafeSender> sender_;
66 const int routing_id_;
67
68 DISALLOW_COPY_AND_ASSIGN(IframeSurfaceReferenceFactory);
69};
70
71class BrowserPluginSurfaceReferenceFactory
72 : public cc::SequenceSurfaceReferenceFactory {
73 public:
74 BrowserPluginSurfaceReferenceFactory(scoped_refptr<ThreadSafeSender> sender,
75 int routing_id,
76 int browser_plugin_instance_id)
77 : sender_(std::move(sender)),
78 routing_id_(routing_id),
79 browser_plugin_instance_id_(browser_plugin_instance_id) {}
80
81 private:
82 ~BrowserPluginSurfaceReferenceFactory() override = default;
83
84 // cc::SequenceSurfaceRefrenceFactory implementation:
85 void SatisfySequence(const cc::SurfaceSequence& seq) const override {
86 sender_->Send(new BrowserPluginHostMsg_SatisfySequence(
87 routing_id_, browser_plugin_instance_id_, seq));
88 }
89
90 void RequireSequence(const cc::SurfaceId& surface_id,
91 const cc::SurfaceSequence& sequence) const override {
92 sender_->Send(new BrowserPluginHostMsg_RequireSequence(
93 routing_id_, browser_plugin_instance_id_, surface_id, sequence));
94 }
95
96 const scoped_refptr<ThreadSafeSender> sender_;
97 const int routing_id_;
98 const int browser_plugin_instance_id_;
99
100 DISALLOW_COPY_AND_ASSIGN(BrowserPluginSurfaceReferenceFactory);
101};
102
103} // namespace
104
[email protected]bffc8302014-01-23 20:52:16105ChildFrameCompositingHelper*
[email protected]c092f5c2014-07-18 01:34:33106ChildFrameCompositingHelper::CreateForBrowserPlugin(
[email protected]94224ba62014-02-04 00:25:24107 const base::WeakPtr<BrowserPlugin>& browser_plugin) {
[email protected]bffc8302014-01-23 20:52:16108 return new ChildFrameCompositingHelper(
kenrbfc7c02c92015-05-29 22:20:58109 browser_plugin, nullptr, nullptr,
110 browser_plugin->render_frame_routing_id());
[email protected]bffc8302014-01-23 20:52:16111}
112
113ChildFrameCompositingHelper*
[email protected]c092f5c2014-07-18 01:34:33114ChildFrameCompositingHelper::CreateForRenderFrameProxy(
115 RenderFrameProxy* render_frame_proxy) {
lfgfd437a272015-11-24 21:24:53116 return new ChildFrameCompositingHelper(
117 base::WeakPtr<BrowserPlugin>(), render_frame_proxy->web_frame(),
118 render_frame_proxy, render_frame_proxy->routing_id());
[email protected]bffc8302014-01-23 20:52:16119}
120
121ChildFrameCompositingHelper::ChildFrameCompositingHelper(
[email protected]94224ba62014-02-04 00:25:24122 const base::WeakPtr<BrowserPlugin>& browser_plugin,
dcheng5cf543012016-11-24 17:13:37123 blink::WebRemoteFrame* frame,
[email protected]e3244ed2014-06-20 20:04:27124 RenderFrameProxy* render_frame_proxy,
[email protected]0f21e8582013-01-11 11:06:56125 int host_routing_id)
[email protected]94224ba62014-02-04 00:25:24126 : host_routing_id_(host_routing_id),
[email protected]94224ba62014-02-04 00:25:24127 browser_plugin_(browser_plugin),
[email protected]e3244ed2014-06-20 20:04:27128 render_frame_proxy_(render_frame_proxy),
samans72b2a282016-12-17 02:44:15129 frame_(frame) {
130 scoped_refptr<ThreadSafeSender> sender(
131 RenderThreadImpl::current()->thread_safe_sender());
132 if (render_frame_proxy_) {
133 surface_reference_factory_ =
134 new IframeSurfaceReferenceFactory(sender, host_routing_id_);
135 } else {
136 surface_reference_factory_ = new BrowserPluginSurfaceReferenceFactory(
137 sender, host_routing_id_,
138 browser_plugin_->browser_plugin_instance_id());
139 }
140}
[email protected]bffc8302014-01-23 20:52:16141
lfga7d368e2015-02-03 23:01:37142ChildFrameCompositingHelper::~ChildFrameCompositingHelper() {
lfga7d368e2015-02-03 23:01:37143}
[email protected]bffc8302014-01-23 20:52:16144
[email protected]94224ba62014-02-04 00:25:24145blink::WebPluginContainer* ChildFrameCompositingHelper::GetContainer() {
146 if (!browser_plugin_)
kenrbfc7c02c92015-05-29 22:20:58147 return nullptr;
[email protected]94224ba62014-02-04 00:25:24148
Blink Reformat1c4d759e2017-04-09 16:34:54149 return browser_plugin_->Container();
[email protected]94224ba62014-02-04 00:25:24150}
151
vmpstre87ffcaa2016-08-23 21:01:14152void ChildFrameCompositingHelper::UpdateWebLayer(
153 std::unique_ptr<blink::WebLayer> layer) {
[email protected]94224ba62014-02-04 00:25:24154 if (GetContainer()) {
Blink Reformat1c4d759e2017-04-09 16:34:54155 GetContainer()->SetWebLayer(layer.get());
[email protected]94224ba62014-02-04 00:25:24156 } else if (frame_) {
Blink Reformat1c4d759e2017-04-09 16:34:54157 frame_->SetWebLayer(layer.get());
[email protected]bffc8302014-01-23 20:52:16158 }
vmpstre87ffcaa2016-08-23 21:01:14159 web_layer_ = std::move(layer);
[email protected]0f21e8582013-01-11 11:06:56160}
161
[email protected]bffc8302014-01-23 20:52:16162void ChildFrameCompositingHelper::CheckSizeAndAdjustLayerProperties(
[email protected]f5b4b0f2013-04-02 18:16:28163 const gfx::Size& new_size,
164 float device_scale_factor,
165 cc::Layer* layer) {
166 if (buffer_size_ != new_size) {
167 buffer_size_ = new_size;
168 // The container size is in DIP, so is the layer size.
169 // Buffer size is in physical pixels, so we need to adjust
170 // it by the device scale factor.
danakjddaec912015-09-25 19:38:40171 gfx::Size device_scale_adjusted_size =
172 gfx::ScaleToFlooredSize(buffer_size_, 1.0f / device_scale_factor);
[email protected]f5b4b0f2013-04-02 18:16:28173 layer->SetBounds(device_scale_adjusted_size);
174 }
175}
176
[email protected]bffc8302014-01-23 20:52:16177void ChildFrameCompositingHelper::OnContainerDestroy() {
lfgfd437a272015-11-24 21:24:53178 UpdateWebLayer(nullptr);
[email protected]0d25cb62013-01-21 15:42:21179}
180
[email protected]f49722f2014-01-30 17:54:50181void ChildFrameCompositingHelper::ChildFrameGone() {
lfgfd437a272015-11-24 21:24:53182 scoped_refptr<cc::SolidColorLayer> crashed_layer =
loyso0940d412016-03-14 01:30:31183 cc::SolidColorLayer::Create();
lfgfd437a272015-11-24 21:24:53184 crashed_layer->SetMasksToBounds(true);
lfgcccffbe2016-03-10 00:05:46185 crashed_layer->SetBackgroundColor(SK_ColorBLACK);
186
187 if (web_layer_) {
188 SkBitmap* sad_bitmap =
189 GetContentClient()->renderer()->GetSadWebViewBitmap();
Blink Reformat1c4d759e2017-04-09 16:34:54190 if (sad_bitmap && web_layer_->Bounds().width > sad_bitmap->width() &&
191 web_layer_->Bounds().height > sad_bitmap->height()) {
lfgcccffbe2016-03-10 00:05:46192 scoped_refptr<cc::PictureImageLayer> sad_layer =
loyso0940d412016-03-14 01:30:31193 cc::PictureImageLayer::Create();
tomhudson992ec28b2016-04-27 16:45:39194 sad_layer->SetImage(SkImage::MakeFromBitmap(*sad_bitmap));
lfgcccffbe2016-03-10 00:05:46195 sad_layer->SetBounds(
196 gfx::Size(sad_bitmap->width(), sad_bitmap->height()));
197 sad_layer->SetPosition(gfx::PointF(
Blink Reformat1c4d759e2017-04-09 16:34:54198 (web_layer_->Bounds().width - sad_bitmap->width()) / 2,
199 (web_layer_->Bounds().height - sad_bitmap->height()) / 2));
lfgcccffbe2016-03-10 00:05:46200 sad_layer->SetIsDrawable(true);
201
202 crashed_layer->AddChild(sad_layer);
203 }
204 }
205
vmpstre87ffcaa2016-08-23 21:01:14206 std::unique_ptr<blink::WebLayer> layer(
207 new cc_blink::WebLayerImpl(crashed_layer));
208 UpdateWebLayer(std::move(layer));
[email protected]f49722f2014-01-30 17:54:50209}
210
kenrbfc7c02c92015-05-29 22:20:58211void ChildFrameCompositingHelper::OnSetSurface(
fsamuel96795522017-01-04 02:41:32212 const cc::SurfaceInfo& surface_info,
kenrbfc7c02c92015-05-29 22:20:58213 const cc::SurfaceSequence& sequence) {
fsamuel96795522017-01-04 02:41:32214 float scale_factor = surface_info.device_scale_factor();
215 surface_id_ = surface_info.id();
lfgfd437a272015-11-24 21:24:53216 scoped_refptr<cc::SurfaceLayer> surface_layer =
samans72b2a282016-12-17 02:44:15217 cc::SurfaceLayer::Create(surface_reference_factory_);
oshima9000e422016-01-27 03:05:36218 // TODO(oshima): This is a stopgap fix so that the compositor does not
219 // scaledown the content when 2x frame data is added to 1x parent frame data.
220 // Fix this in cc/.
221 if (IsUseZoomForDSFEnabled())
222 scale_factor = 1.0f;
fsamuel96795522017-01-04 02:41:32223
fsamuel1d3252c2017-02-15 20:56:37224 surface_layer->SetPrimarySurfaceInfo(cc::SurfaceInfo(
225 surface_info.id(), scale_factor, surface_info.size_in_pixels()));
lfg042482c2016-01-21 03:53:55226 surface_layer->SetMasksToBounds(true);
vmpstre87ffcaa2016-08-23 21:01:14227 std::unique_ptr<cc_blink::WebLayerImpl> layer(
228 new cc_blink::WebLayerImpl(surface_layer));
lfg04c6bd602016-07-20 17:02:52229 // TODO(lfg): Investigate if it's possible to propagate the information about
230 // the child surface's opacity. https://crbug.com/629851.
Blink Reformat1c4d759e2017-04-09 16:34:54231 layer->SetOpaque(false);
lfg04c6bd602016-07-20 17:02:52232 layer->SetContentsOpaqueIsFixed(true);
vmpstre87ffcaa2016-08-23 21:01:14233 UpdateWebLayer(std::move(layer));
kenrbfc7c02c92015-05-29 22:20:58234
kenrbfc7c02c92015-05-29 22:20:58235 UpdateVisibility(true);
kenrbfc7c02c92015-05-29 22:20:58236
237 // The RWHV creates a destruction dependency on the surface that needs to be
wjmaclean53032adf2015-06-15 16:49:22238 // satisfied. Note: render_frame_proxy_ is null in the case our client is a
239 // BrowserPlugin; in this case the BrowserPlugin sends its own SatisfySequence
240 // message.
241 if (render_frame_proxy_) {
242 render_frame_proxy_->Send(
243 new FrameHostMsg_SatisfySequence(host_routing_id_, sequence));
244 } else if (browser_plugin_.get()) {
245 browser_plugin_->SendSatisfySequence(sequence);
246 }
kenrbfc7c02c92015-05-29 22:20:58247
lfgfd437a272015-11-24 21:24:53248 CheckSizeAndAdjustLayerProperties(
fsamuel96795522017-01-04 02:41:32249 surface_info.size_in_pixels(), surface_info.device_scale_factor(),
lfgfd437a272015-11-24 21:24:53250 static_cast<cc_blink::WebLayerImpl*>(web_layer_.get())->layer());
kenrbfc7c02c92015-05-29 22:20:58251}
252
[email protected]bffc8302014-01-23 20:52:16253void ChildFrameCompositingHelper::UpdateVisibility(bool visible) {
lfgfd437a272015-11-24 21:24:53254 if (web_layer_)
Blink Reformat1c4d759e2017-04-09 16:34:54255 web_layer_->SetDrawsContent(visible);
[email protected]69b79122013-02-14 19:16:45256}
257
[email protected]0f21e8582013-01-11 11:06:56258} // namespace content