blob: 08293fd016ff560655c08a4ed87fc33cfcf4756f [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
[email protected]38564622014-08-19 02:47:187#include "cc/blink/web_layer_impl.h"
[email protected]09f67382013-10-09 21:03:458#include "cc/layers/delegated_frame_provider.h"
9#include "cc/layers/delegated_frame_resource_collection.h"
[email protected]f5b4b0f2013-04-02 18:16:2810#include "cc/layers/delegated_renderer_layer.h"
[email protected]cc3cfaa2013-03-18 09:05:5211#include "cc/layers/solid_color_layer.h"
[email protected]7f0d825f2013-03-18 07:24:3012#include "cc/output/context_provider.h"
[email protected]73405fb2013-12-11 04:59:3713#include "cc/output/copy_output_request.h"
14#include "cc/output/copy_output_result.h"
[email protected]9260757f2013-09-17 01:24:1615#include "cc/resources/single_release_callback.h"
[email protected]703dd662013-03-05 07:37:4216#include "content/common/browser_plugin/browser_plugin_messages.h"
[email protected]95d31822014-01-03 22:21:5517#include "content/common/frame_messages.h"
[email protected]a45c46e2013-03-07 01:04:4618#include "content/common/gpu/client/context_provider_command_buffer.h"
[email protected]94224ba62014-02-04 00:25:2419#include "content/renderer/browser_plugin/browser_plugin.h"
[email protected]0d25cb62013-01-21 15:42:2120#include "content/renderer/browser_plugin/browser_plugin_manager.h"
[email protected]bffc8302014-01-23 20:52:1621#include "content/renderer/render_frame_impl.h"
[email protected]e3244ed2014-06-20 20:04:2722#include "content/renderer/render_frame_proxy.h"
[email protected]0f21e8582013-01-11 11:06:5623#include "content/renderer/render_thread_impl.h"
[email protected]73405fb2013-12-11 04:59:3724#include "skia/ext/image_operations.h"
[email protected]bffc8302014-01-23 20:52:1625#include "third_party/WebKit/public/web/WebFrame.h"
[email protected]2255a9332013-06-17 05:12:3126#include "third_party/WebKit/public/web/WebPluginContainer.h"
[email protected]7f0d825f2013-03-18 07:24:3027#include "third_party/khronos/GLES2/gl2.h"
tfarinaebe974f02015-01-03 04:25:3228#include "ui/gfx/geometry/size_conversions.h"
[email protected]73405fb2013-12-11 04:59:3729#include "ui/gfx/skia_util.h"
[email protected]0f21e8582013-01-11 11:06:5630
31namespace content {
32
[email protected]bffc8302014-01-23 20:52:1633ChildFrameCompositingHelper*
[email protected]c092f5c2014-07-18 01:34:3334ChildFrameCompositingHelper::CreateForBrowserPlugin(
[email protected]94224ba62014-02-04 00:25:2435 const base::WeakPtr<BrowserPlugin>& browser_plugin) {
[email protected]bffc8302014-01-23 20:52:1636 return new ChildFrameCompositingHelper(
[email protected]94224ba62014-02-04 00:25:2437 browser_plugin, NULL, NULL, browser_plugin->render_view_routing_id());
[email protected]bffc8302014-01-23 20:52:1638}
39
40ChildFrameCompositingHelper*
[email protected]c092f5c2014-07-18 01:34:3341ChildFrameCompositingHelper::CreateForRenderFrameProxy(
42 RenderFrameProxy* render_frame_proxy) {
43 return new ChildFrameCompositingHelper(base::WeakPtr<BrowserPlugin>(),
44 render_frame_proxy->web_frame(),
45 render_frame_proxy,
46 render_frame_proxy->routing_id());
[email protected]bffc8302014-01-23 20:52:1647}
48
49ChildFrameCompositingHelper::ChildFrameCompositingHelper(
[email protected]94224ba62014-02-04 00:25:2450 const base::WeakPtr<BrowserPlugin>& browser_plugin,
[email protected]bffc8302014-01-23 20:52:1651 blink::WebFrame* frame,
[email protected]e3244ed2014-06-20 20:04:2752 RenderFrameProxy* render_frame_proxy,
[email protected]0f21e8582013-01-11 11:06:5653 int host_routing_id)
[email protected]94224ba62014-02-04 00:25:2454 : host_routing_id_(host_routing_id),
[email protected]f5b4b0f2013-04-02 18:16:2855 last_route_id_(0),
[email protected]53b4cc12013-07-18 23:02:3056 last_output_surface_id_(0),
[email protected]f5b4b0f2013-04-02 18:16:2857 last_host_id_(0),
[email protected]0d25cb62013-01-21 15:42:2158 ack_pending_(true),
[email protected]6d3a46e2013-11-25 23:08:5359 opaque_(true),
[email protected]94224ba62014-02-04 00:25:2460 browser_plugin_(browser_plugin),
[email protected]e3244ed2014-06-20 20:04:2761 render_frame_proxy_(render_frame_proxy),
[email protected]bdca9be22014-02-18 00:37:4962 frame_(frame) {}
[email protected]bffc8302014-01-23 20:52:1663
lfga7d368e2015-02-03 23:01:3764ChildFrameCompositingHelper::~ChildFrameCompositingHelper() {
65 if (resource_collection_.get())
66 resource_collection_->SetClient(NULL);
67}
[email protected]bffc8302014-01-23 20:52:1668
[email protected]94224ba62014-02-04 00:25:2469BrowserPluginManager* ChildFrameCompositingHelper::GetBrowserPluginManager() {
70 if (!browser_plugin_)
71 return NULL;
72
fsamuel6c1dfeb2014-12-18 19:21:3373 return BrowserPluginManager::Get();
[email protected]94224ba62014-02-04 00:25:2474}
75
76blink::WebPluginContainer* ChildFrameCompositingHelper::GetContainer() {
77 if (!browser_plugin_)
78 return NULL;
79
80 return browser_plugin_->container();
81}
82
83int ChildFrameCompositingHelper::GetInstanceID() {
84 if (!browser_plugin_)
85 return 0;
86
[email protected]2101c4c2014-08-22 00:16:1687 return browser_plugin_->browser_plugin_instance_id();
[email protected]94224ba62014-02-04 00:25:2488}
89
[email protected]bffc8302014-01-23 20:52:1690void ChildFrameCompositingHelper::SendCompositorFrameSwappedACKToBrowser(
91 FrameHostMsg_CompositorFrameSwappedACK_Params& params) {
92 // This function will be removed when BrowserPluginManager is removed and
93 // BrowserPlugin is modified to use a RenderFrame.
[email protected]94224ba62014-02-04 00:25:2494 if (GetBrowserPluginManager()) {
95 GetBrowserPluginManager()->Send(
[email protected]bffc8302014-01-23 20:52:1696 new BrowserPluginHostMsg_CompositorFrameSwappedACK(
[email protected]94224ba62014-02-04 00:25:2497 host_routing_id_, GetInstanceID(), params));
[email protected]e3244ed2014-06-20 20:04:2798 } else if (render_frame_proxy_) {
99 render_frame_proxy_->Send(
[email protected]bffc8302014-01-23 20:52:16100 new FrameHostMsg_CompositorFrameSwappedACK(host_routing_id_, params));
101 }
[email protected]0f21e8582013-01-11 11:06:56102}
103
[email protected]bffc8302014-01-23 20:52:16104void ChildFrameCompositingHelper::SendReclaimCompositorResourcesToBrowser(
105 FrameHostMsg_ReclaimCompositorResources_Params& params) {
106 // This function will be removed when BrowserPluginManager is removed and
107 // BrowserPlugin is modified to use a RenderFrame.
[email protected]94224ba62014-02-04 00:25:24108 if (GetBrowserPluginManager()) {
109 GetBrowserPluginManager()->Send(
[email protected]bffc8302014-01-23 20:52:16110 new BrowserPluginHostMsg_ReclaimCompositorResources(
[email protected]94224ba62014-02-04 00:25:24111 host_routing_id_, GetInstanceID(), params));
[email protected]e3244ed2014-06-20 20:04:27112 } else if (render_frame_proxy_) {
113 render_frame_proxy_->Send(
[email protected]bffc8302014-01-23 20:52:16114 new FrameHostMsg_ReclaimCompositorResources(host_routing_id_, params));
115 }
116}
117
[email protected]bffc8302014-01-23 20:52:16118void ChildFrameCompositingHelper::DidCommitCompositorFrame() {
[email protected]09f67382013-10-09 21:03:45119 if (!resource_collection_.get() || !ack_pending_)
[email protected]f5b4b0f2013-04-02 18:16:28120 return;
[email protected]396fbb72013-01-23 02:33:43121
[email protected]95d31822014-01-03 22:21:55122 FrameHostMsg_CompositorFrameSwappedACK_Params params;
123 params.producing_host_id = last_host_id_;
124 params.producing_route_id = last_route_id_;
125 params.output_surface_id = last_output_surface_id_;
126 resource_collection_->TakeUnusedResourcesForChildCompositor(
127 &params.ack.resources);
[email protected]f5b4b0f2013-04-02 18:16:28128
[email protected]bffc8302014-01-23 20:52:16129 SendCompositorFrameSwappedACKToBrowser(params);
[email protected]f5b4b0f2013-04-02 18:16:28130
131 ack_pending_ = false;
132}
133
[email protected]bffc8302014-01-23 20:52:16134void ChildFrameCompositingHelper::EnableCompositing(bool enable) {
[email protected]fc72bb12013-06-02 21:13:46135 if (enable && !background_layer_.get()) {
[email protected]67be9b1d2013-03-08 02:27:45136 background_layer_ = cc::SolidColorLayer::Create();
[email protected]7aba6662013-03-12 10:17:34137 background_layer_->SetMasksToBounds(true);
138 background_layer_->SetBackgroundColor(
[email protected]396fbb72013-01-23 02:33:43139 SkColorSetARGBInline(255, 255, 255, 255));
[email protected]38564622014-08-19 02:47:18140 web_layer_.reset(new cc_blink::WebLayerImpl(background_layer_));
[email protected]0f21e8582013-01-11 11:06:56141 }
142
[email protected]94224ba62014-02-04 00:25:24143 if (GetContainer()) {
144 GetContainer()->setWebLayer(enable ? web_layer_.get() : NULL);
145 } else if (frame_) {
[email protected]bffc8302014-01-23 20:52:16146 frame_->setRemoteWebLayer(enable ? web_layer_.get() : NULL);
147 }
[email protected]0f21e8582013-01-11 11:06:56148}
149
[email protected]bffc8302014-01-23 20:52:16150void ChildFrameCompositingHelper::CheckSizeAndAdjustLayerProperties(
[email protected]f5b4b0f2013-04-02 18:16:28151 const gfx::Size& new_size,
152 float device_scale_factor,
153 cc::Layer* layer) {
154 if (buffer_size_ != new_size) {
155 buffer_size_ = new_size;
156 // The container size is in DIP, so is the layer size.
157 // Buffer size is in physical pixels, so we need to adjust
158 // it by the device scale factor.
159 gfx::Size device_scale_adjusted_size = gfx::ToFlooredSize(
160 gfx::ScaleSize(buffer_size_, 1.0f / device_scale_factor));
161 layer->SetBounds(device_scale_adjusted_size);
162 }
[email protected]6d3a46e2013-11-25 23:08:53163
164 // Manually manage background layer for transparent webview.
165 if (!opaque_)
166 background_layer_->SetIsDrawable(false);
[email protected]f5b4b0f2013-04-02 18:16:28167}
168
[email protected]bffc8302014-01-23 20:52:16169void ChildFrameCompositingHelper::OnContainerDestroy() {
fsamuel0147b102014-11-10 17:05:01170 // If we have a pending ACK, then ACK now so we don't lose frames in the
171 // future.
172 DidCommitCompositorFrame();
173
[email protected]94224ba62014-02-04 00:25:24174 if (GetContainer())
175 GetContainer()->setWebLayer(NULL);
[email protected]0d25cb62013-01-21 15:42:21176
dcheng58867a92014-08-26 02:50:22177 if (resource_collection_.get())
[email protected]b0030b72013-11-15 20:35:53178 resource_collection_->SetClient(NULL);
179
[email protected]7873fe4e2013-11-14 18:35:22180 ack_pending_ = false;
[email protected]b0030b72013-11-15 20:35:53181 resource_collection_ = NULL;
182 frame_provider_ = NULL;
[email protected]f5b4b0f2013-04-02 18:16:28183 delegated_layer_ = NULL;
[email protected]396fbb72013-01-23 02:33:43184 background_layer_ = NULL;
[email protected]0d25cb62013-01-21 15:42:21185 web_layer_.reset();
186}
187
[email protected]f49722f2014-01-30 17:54:50188void ChildFrameCompositingHelper::ChildFrameGone() {
189 background_layer_->SetBackgroundColor(SkColorSetARGBInline(255, 0, 128, 0));
190 background_layer_->RemoveAllChildren();
191 background_layer_->SetIsDrawable(true);
192 background_layer_->SetContentsOpaque(true);
193}
194
[email protected]bffc8302014-01-23 20:52:16195void ChildFrameCompositingHelper::OnCompositorFrameSwapped(
[email protected]f5b4b0f2013-04-02 18:16:28196 scoped_ptr<cc::CompositorFrame> frame,
197 int route_id,
[email protected]53b4cc12013-07-18 23:02:30198 uint32 output_surface_id,
[email protected]f1970082014-04-09 04:29:56199 int host_id,
200 base::SharedMemoryHandle handle) {
[email protected]09f67382013-10-09 21:03:45201 cc::DelegatedFrameData* frame_data = frame->delegated_frame_data.get();
[email protected]b0030b72013-11-15 20:35:53202 // Do nothing if we are getting destroyed or have no frame data.
dcheng58867a92014-08-26 02:50:22203 if (!frame_data || !background_layer_.get())
[email protected]f5b4b0f2013-04-02 18:16:28204 return;
205
[email protected]09f67382013-10-09 21:03:45206 DCHECK(!frame_data->render_pass_list.empty());
207 cc::RenderPass* root_pass = frame_data->render_pass_list.back();
208 gfx::Size frame_size = root_pass->output_rect.size();
209
[email protected]317f17d2013-11-09 05:03:48210 if (last_route_id_ != route_id ||
211 last_output_surface_id_ != output_surface_id ||
212 last_host_id_ != host_id) {
213 // Resource ids are scoped by the output surface.
214 // If the originating output surface doesn't match the last one, it
215 // indicates the guest's output surface may have been recreated, in which
216 // case we should recreate the DelegatedRendererLayer, to avoid matching
217 // resources from the old one with resources from the new one which would
218 // have the same id.
219 frame_provider_ = NULL;
220
221 // Drop the cc::DelegatedFrameResourceCollection so that we will not return
222 // any resources from the old output surface with the new output surface id.
dcheng58867a92014-08-26 02:50:22223 if (resource_collection_.get()) {
[email protected]b0030b72013-11-15 20:35:53224 resource_collection_->SetClient(NULL);
225
226 if (resource_collection_->LoseAllResources())
227 SendReturnedDelegatedResources();
[email protected]317f17d2013-11-09 05:03:48228 resource_collection_ = NULL;
229 }
230 last_output_surface_id_ = output_surface_id;
231 last_route_id_ = route_id;
232 last_host_id_ = host_id;
233 }
dcheng58867a92014-08-26 02:50:22234 if (!resource_collection_.get()) {
[email protected]09f67382013-10-09 21:03:45235 resource_collection_ = new cc::DelegatedFrameResourceCollection;
[email protected]b0030b72013-11-15 20:35:53236 resource_collection_->SetClient(this);
[email protected]09f67382013-10-09 21:03:45237 }
238 if (!frame_provider_.get() || frame_provider_->frame_size() != frame_size) {
239 frame_provider_ = new cc::DelegatedFrameProvider(
240 resource_collection_.get(), frame->delegated_frame_data.Pass());
241 if (delegated_layer_.get())
242 delegated_layer_->RemoveFromParent();
243 delegated_layer_ =
[email protected]b59c1612013-12-04 00:56:49244 cc::DelegatedRendererLayer::Create(frame_provider_.get());
[email protected]09f67382013-10-09 21:03:45245 delegated_layer_->SetIsDrawable(true);
fsamuele9741a32014-09-09 05:34:07246 buffer_size_ = gfx::Size();
[email protected]6d3a46e2013-11-25 23:08:53247 SetContentsOpaque(opaque_);
[email protected]09f67382013-10-09 21:03:45248 background_layer_->AddChild(delegated_layer_);
249 } else {
250 frame_provider_->SetFrameData(frame->delegated_frame_data.Pass());
251 }
252
[email protected]6d3a46e2013-11-25 23:08:53253 CheckSizeAndAdjustLayerProperties(
[email protected]f5b4b0f2013-04-02 18:16:28254 frame_data->render_pass_list.back()->output_rect.size(),
255 frame->metadata.device_scale_factor,
256 delegated_layer_.get());
257
[email protected]f5b4b0f2013-04-02 18:16:28258 ack_pending_ = true;
259}
260
[email protected]bffc8302014-01-23 20:52:16261void ChildFrameCompositingHelper::UpdateVisibility(bool visible) {
[email protected]fc72bb12013-06-02 21:13:46262 if (delegated_layer_.get())
[email protected]f5b4b0f2013-04-02 18:16:28263 delegated_layer_->SetIsDrawable(visible);
[email protected]69b79122013-02-14 19:16:45264}
265
[email protected]bffc8302014-01-23 20:52:16266void ChildFrameCompositingHelper::UnusedResourcesAreAvailable() {
[email protected]b0030b72013-11-15 20:35:53267 if (ack_pending_)
268 return;
269
270 SendReturnedDelegatedResources();
271}
272
[email protected]bffc8302014-01-23 20:52:16273void ChildFrameCompositingHelper::SendReturnedDelegatedResources() {
274 FrameHostMsg_ReclaimCompositorResources_Params params;
dcheng58867a92014-08-26 02:50:22275 if (resource_collection_.get())
[email protected]bffc8302014-01-23 20:52:16276 resource_collection_->TakeUnusedResourcesForChildCompositor(
277 &params.ack.resources);
278 DCHECK(!params.ack.resources.empty());
[email protected]b0030b72013-11-15 20:35:53279
[email protected]bffc8302014-01-23 20:52:16280 params.route_id = last_route_id_;
281 params.output_surface_id = last_output_surface_id_;
282 params.renderer_host_id = last_host_id_;
283 SendReclaimCompositorResourcesToBrowser(params);
[email protected]b0030b72013-11-15 20:35:53284}
285
[email protected]bffc8302014-01-23 20:52:16286void ChildFrameCompositingHelper::SetContentsOpaque(bool opaque) {
[email protected]6d3a46e2013-11-25 23:08:53287 opaque_ = opaque;
[email protected]6d3a46e2013-11-25 23:08:53288 if (delegated_layer_.get())
289 delegated_layer_->SetContentsOpaque(opaque_);
290}
291
[email protected]0f21e8582013-01-11 11:06:56292} // namespace content