blob: 5e921cbbbe33e0eb44ac3073a5762b361e562994 [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"
12#include "cc/layers/texture_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"
[email protected]703dd662013-03-05 07:37:4217#include "content/common/browser_plugin/browser_plugin_messages.h"
[email protected]95d31822014-01-03 22:21:5518#include "content/common/frame_messages.h"
[email protected]a45c46e2013-03-07 01:04:4619#include "content/common/gpu/client/context_provider_command_buffer.h"
[email protected]94224ba62014-02-04 00:25:2420#include "content/renderer/browser_plugin/browser_plugin.h"
[email protected]0d25cb62013-01-21 15:42:2121#include "content/renderer/browser_plugin/browser_plugin_manager.h"
[email protected]bffc8302014-01-23 20:52:1622#include "content/renderer/render_frame_impl.h"
[email protected]e3244ed2014-06-20 20:04:2723#include "content/renderer/render_frame_proxy.h"
[email protected]0f21e8582013-01-11 11:06:5624#include "content/renderer/render_thread_impl.h"
[email protected]73405fb2013-12-11 04:59:3725#include "skia/ext/image_operations.h"
[email protected]5c30b5e02013-05-30 03:46:0826#include "third_party/WebKit/public/platform/WebGraphicsContext3D.h"
[email protected]bffc8302014-01-23 20:52:1627#include "third_party/WebKit/public/web/WebFrame.h"
[email protected]2255a9332013-06-17 05:12:3128#include "third_party/WebKit/public/web/WebPluginContainer.h"
[email protected]7f0d825f2013-03-18 07:24:3029#include "third_party/khronos/GLES2/gl2.h"
[email protected]7e95a6d2013-03-04 23:31:3430#include "ui/gfx/size_conversions.h"
[email protected]73405fb2013-12-11 04:59:3731#include "ui/gfx/skia_util.h"
[email protected]0f21e8582013-01-11 11:06:5632
33namespace content {
34
[email protected]bffc8302014-01-23 20:52:1635ChildFrameCompositingHelper::SwapBuffersInfo::SwapBuffersInfo()
[email protected]9f39c202013-06-18 16:06:4236 : route_id(0),
[email protected]53b4cc12013-07-18 23:02:3037 output_surface_id(0),
[email protected]9f39c202013-06-18 16:06:4238 host_id(0),
39 software_frame_id(0),
[email protected]bffc8302014-01-23 20:52:1640 shared_memory(NULL) {}
[email protected]9f39c202013-06-18 16:06:4241
[email protected]bffc8302014-01-23 20:52:1642ChildFrameCompositingHelper*
[email protected]c092f5c2014-07-18 01:34:3343ChildFrameCompositingHelper::CreateForBrowserPlugin(
[email protected]94224ba62014-02-04 00:25:2444 const base::WeakPtr<BrowserPlugin>& browser_plugin) {
[email protected]bffc8302014-01-23 20:52:1645 return new ChildFrameCompositingHelper(
[email protected]94224ba62014-02-04 00:25:2446 browser_plugin, NULL, NULL, browser_plugin->render_view_routing_id());
[email protected]bffc8302014-01-23 20:52:1647}
48
49ChildFrameCompositingHelper*
[email protected]c092f5c2014-07-18 01:34:3350ChildFrameCompositingHelper::CreateForRenderFrameProxy(
51 RenderFrameProxy* render_frame_proxy) {
52 return new ChildFrameCompositingHelper(base::WeakPtr<BrowserPlugin>(),
53 render_frame_proxy->web_frame(),
54 render_frame_proxy,
55 render_frame_proxy->routing_id());
[email protected]bffc8302014-01-23 20:52:1656}
57
58ChildFrameCompositingHelper::ChildFrameCompositingHelper(
[email protected]94224ba62014-02-04 00:25:2459 const base::WeakPtr<BrowserPlugin>& browser_plugin,
[email protected]bffc8302014-01-23 20:52:1660 blink::WebFrame* frame,
[email protected]e3244ed2014-06-20 20:04:2761 RenderFrameProxy* render_frame_proxy,
[email protected]0f21e8582013-01-11 11:06:5662 int host_routing_id)
[email protected]94224ba62014-02-04 00:25:2463 : host_routing_id_(host_routing_id),
[email protected]f5b4b0f2013-04-02 18:16:2864 last_route_id_(0),
[email protected]53b4cc12013-07-18 23:02:3065 last_output_surface_id_(0),
[email protected]f5b4b0f2013-04-02 18:16:2866 last_host_id_(0),
[email protected]0f21e8582013-01-11 11:06:5667 last_mailbox_valid_(false),
[email protected]0d25cb62013-01-21 15:42:2168 ack_pending_(true),
[email protected]9afdaef2013-09-26 07:24:3769 software_ack_pending_(false),
[email protected]6d3a46e2013-11-25 23:08:5370 opaque_(true),
[email protected]94224ba62014-02-04 00:25:2471 browser_plugin_(browser_plugin),
[email protected]e3244ed2014-06-20 20:04:2772 render_frame_proxy_(render_frame_proxy),
[email protected]bdca9be22014-02-18 00:37:4973 frame_(frame) {}
[email protected]bffc8302014-01-23 20:52:1674
75ChildFrameCompositingHelper::~ChildFrameCompositingHelper() {}
76
[email protected]94224ba62014-02-04 00:25:2477BrowserPluginManager* ChildFrameCompositingHelper::GetBrowserPluginManager() {
78 if (!browser_plugin_)
79 return NULL;
80
81 return browser_plugin_->browser_plugin_manager();
82}
83
84blink::WebPluginContainer* ChildFrameCompositingHelper::GetContainer() {
85 if (!browser_plugin_)
86 return NULL;
87
88 return browser_plugin_->container();
89}
90
91int ChildFrameCompositingHelper::GetInstanceID() {
92 if (!browser_plugin_)
93 return 0;
94
[email protected]2101c4c2014-08-22 00:16:1695 return browser_plugin_->browser_plugin_instance_id();
[email protected]94224ba62014-02-04 00:25:2496}
97
[email protected]bffc8302014-01-23 20:52:1698void ChildFrameCompositingHelper::SendCompositorFrameSwappedACKToBrowser(
99 FrameHostMsg_CompositorFrameSwappedACK_Params& params) {
100 // This function will be removed when BrowserPluginManager is removed and
101 // BrowserPlugin is modified to use a RenderFrame.
[email protected]94224ba62014-02-04 00:25:24102 if (GetBrowserPluginManager()) {
103 GetBrowserPluginManager()->Send(
[email protected]bffc8302014-01-23 20:52:16104 new BrowserPluginHostMsg_CompositorFrameSwappedACK(
[email protected]94224ba62014-02-04 00:25:24105 host_routing_id_, GetInstanceID(), params));
[email protected]e3244ed2014-06-20 20:04:27106 } else if (render_frame_proxy_) {
107 render_frame_proxy_->Send(
[email protected]bffc8302014-01-23 20:52:16108 new FrameHostMsg_CompositorFrameSwappedACK(host_routing_id_, params));
109 }
[email protected]0f21e8582013-01-11 11:06:56110}
111
[email protected]bffc8302014-01-23 20:52:16112void ChildFrameCompositingHelper::SendBuffersSwappedACKToBrowser(
113 FrameHostMsg_BuffersSwappedACK_Params& params) {
114 // This function will be removed when BrowserPluginManager is removed and
115 // BrowserPlugin is modified to use a RenderFrame.
[email protected]94224ba62014-02-04 00:25:24116 if (GetBrowserPluginManager()) {
117 GetBrowserPluginManager()->Send(new BrowserPluginHostMsg_BuffersSwappedACK(
[email protected]eb455d382014-04-12 10:54:23118 host_routing_id_, params));
[email protected]e3244ed2014-06-20 20:04:27119 } else if (render_frame_proxy_) {
120 render_frame_proxy_->Send(
[email protected]bffc8302014-01-23 20:52:16121 new FrameHostMsg_BuffersSwappedACK(host_routing_id_, params));
122 }
[email protected]0f21e8582013-01-11 11:06:56123}
124
[email protected]bffc8302014-01-23 20:52:16125void ChildFrameCompositingHelper::SendReclaimCompositorResourcesToBrowser(
126 FrameHostMsg_ReclaimCompositorResources_Params& params) {
127 // This function will be removed when BrowserPluginManager is removed and
128 // BrowserPlugin is modified to use a RenderFrame.
[email protected]94224ba62014-02-04 00:25:24129 if (GetBrowserPluginManager()) {
130 GetBrowserPluginManager()->Send(
[email protected]bffc8302014-01-23 20:52:16131 new BrowserPluginHostMsg_ReclaimCompositorResources(
[email protected]94224ba62014-02-04 00:25:24132 host_routing_id_, GetInstanceID(), params));
[email protected]e3244ed2014-06-20 20:04:27133 } else if (render_frame_proxy_) {
134 render_frame_proxy_->Send(
[email protected]bffc8302014-01-23 20:52:16135 new FrameHostMsg_ReclaimCompositorResources(host_routing_id_, params));
136 }
137}
138
139void ChildFrameCompositingHelper::CopyFromCompositingSurface(
[email protected]73405fb2013-12-11 04:59:37140 int request_id,
141 gfx::Rect source_rect,
142 gfx::Size dest_size) {
143 CHECK(background_layer_);
144 scoped_ptr<cc::CopyOutputRequest> request =
145 cc::CopyOutputRequest::CreateBitmapRequest(base::Bind(
[email protected]bffc8302014-01-23 20:52:16146 &ChildFrameCompositingHelper::CopyFromCompositingSurfaceHasResult,
[email protected]73405fb2013-12-11 04:59:37147 this,
148 request_id,
149 dest_size));
150 request->set_area(source_rect);
151 background_layer_->RequestCopyOfOutput(request.Pass());
152}
153
[email protected]bffc8302014-01-23 20:52:16154void ChildFrameCompositingHelper::DidCommitCompositorFrame() {
[email protected]9afdaef2013-09-26 07:24:37155 if (software_ack_pending_) {
[email protected]95d31822014-01-03 22:21:55156 FrameHostMsg_CompositorFrameSwappedACK_Params params;
157 params.producing_host_id = last_host_id_;
158 params.producing_route_id = last_route_id_;
159 params.output_surface_id = last_output_surface_id_;
[email protected]9afdaef2013-09-26 07:24:37160 if (!unacked_software_frames_.empty()) {
[email protected]95d31822014-01-03 22:21:55161 params.ack.last_software_frame_id = unacked_software_frames_.back();
[email protected]9afdaef2013-09-26 07:24:37162 unacked_software_frames_.pop_back();
163 }
164
[email protected]bffc8302014-01-23 20:52:16165 SendCompositorFrameSwappedACKToBrowser(params);
[email protected]9afdaef2013-09-26 07:24:37166
167 software_ack_pending_ = false;
168 }
[email protected]09f67382013-10-09 21:03:45169 if (!resource_collection_.get() || !ack_pending_)
[email protected]f5b4b0f2013-04-02 18:16:28170 return;
[email protected]396fbb72013-01-23 02:33:43171
[email protected]95d31822014-01-03 22:21:55172 FrameHostMsg_CompositorFrameSwappedACK_Params params;
173 params.producing_host_id = last_host_id_;
174 params.producing_route_id = last_route_id_;
175 params.output_surface_id = last_output_surface_id_;
176 resource_collection_->TakeUnusedResourcesForChildCompositor(
177 &params.ack.resources);
[email protected]f5b4b0f2013-04-02 18:16:28178
[email protected]bffc8302014-01-23 20:52:16179 SendCompositorFrameSwappedACKToBrowser(params);
[email protected]f5b4b0f2013-04-02 18:16:28180
181 ack_pending_ = false;
182}
183
[email protected]bffc8302014-01-23 20:52:16184void ChildFrameCompositingHelper::EnableCompositing(bool enable) {
[email protected]fc72bb12013-06-02 21:13:46185 if (enable && !background_layer_.get()) {
[email protected]67be9b1d2013-03-08 02:27:45186 background_layer_ = cc::SolidColorLayer::Create();
[email protected]7aba6662013-03-12 10:17:34187 background_layer_->SetMasksToBounds(true);
188 background_layer_->SetBackgroundColor(
[email protected]396fbb72013-01-23 02:33:43189 SkColorSetARGBInline(255, 255, 255, 255));
[email protected]38564622014-08-19 02:47:18190 web_layer_.reset(new cc_blink::WebLayerImpl(background_layer_));
[email protected]0f21e8582013-01-11 11:06:56191 }
192
[email protected]94224ba62014-02-04 00:25:24193 if (GetContainer()) {
194 GetContainer()->setWebLayer(enable ? web_layer_.get() : NULL);
195 } else if (frame_) {
[email protected]bffc8302014-01-23 20:52:16196 frame_->setRemoteWebLayer(enable ? web_layer_.get() : NULL);
197 }
[email protected]0f21e8582013-01-11 11:06:56198}
199
[email protected]bffc8302014-01-23 20:52:16200void ChildFrameCompositingHelper::CheckSizeAndAdjustLayerProperties(
[email protected]f5b4b0f2013-04-02 18:16:28201 const gfx::Size& new_size,
202 float device_scale_factor,
203 cc::Layer* layer) {
204 if (buffer_size_ != new_size) {
205 buffer_size_ = new_size;
206 // The container size is in DIP, so is the layer size.
207 // Buffer size is in physical pixels, so we need to adjust
208 // it by the device scale factor.
209 gfx::Size device_scale_adjusted_size = gfx::ToFlooredSize(
210 gfx::ScaleSize(buffer_size_, 1.0f / device_scale_factor));
211 layer->SetBounds(device_scale_adjusted_size);
212 }
[email protected]6d3a46e2013-11-25 23:08:53213
214 // Manually manage background layer for transparent webview.
215 if (!opaque_)
216 background_layer_->SetIsDrawable(false);
[email protected]f5b4b0f2013-04-02 18:16:28217}
218
[email protected]bffc8302014-01-23 20:52:16219void ChildFrameCompositingHelper::MailboxReleased(SwapBuffersInfo mailbox,
[email protected]df41e252014-02-03 23:39:50220 uint32 sync_point,
[email protected]bffc8302014-01-23 20:52:16221 bool lost_resource) {
[email protected]9f39c202013-06-18 16:06:42222 if (mailbox.type == SOFTWARE_COMPOSITOR_FRAME) {
223 delete mailbox.shared_memory;
224 mailbox.shared_memory = NULL;
225 } else if (lost_resource) {
226 // Reset mailbox's name if the resource was lost.
227 mailbox.name.SetZero();
[email protected]7ba3ca72013-04-11 06:37:25228 }
229
[email protected]c049b2e2013-06-11 04:39:30230 // This means the GPU process crashed or guest crashed.
[email protected]53b4cc12013-07-18 23:02:30231 if (last_host_id_ != mailbox.host_id ||
232 last_output_surface_id_ != mailbox.output_surface_id ||
233 last_route_id_ != mailbox.route_id)
[email protected]4f7bbdc2013-01-29 02:31:39234 return;
235
[email protected]9afdaef2013-09-26 07:24:37236 if (mailbox.type == SOFTWARE_COMPOSITOR_FRAME)
237 unacked_software_frames_.push_back(mailbox.software_frame_id);
238
[email protected]c049b2e2013-06-11 04:39:30239 // We need to send an ACK to for every buffer sent to us.
240 // However, if a buffer is freed up from
[email protected]0d25cb62013-01-21 15:42:21241 // the compositor in cases like switching back to SW mode without a new
[email protected]c049b2e2013-06-11 04:39:30242 // buffer arriving, no ACK is needed.
[email protected]0d25cb62013-01-21 15:42:21243 if (!ack_pending_) {
[email protected]0d25cb62013-01-21 15:42:21244 last_mailbox_valid_ = false;
245 return;
246 }
247 ack_pending_ = false;
[email protected]c049b2e2013-06-11 04:39:30248 switch (mailbox.type) {
249 case TEXTURE_IMAGE_TRANSPORT: {
[email protected]95d31822014-01-03 22:21:55250 FrameHostMsg_BuffersSwappedACK_Params params;
251 params.gpu_host_id = mailbox.host_id;
252 params.gpu_route_id = mailbox.route_id;
[email protected]7c6c09e2014-02-15 00:16:17253 params.mailbox = mailbox.name;
[email protected]95d31822014-01-03 22:21:55254 params.sync_point = sync_point;
[email protected]bffc8302014-01-23 20:52:16255 SendBuffersSwappedACKToBrowser(params);
[email protected]c049b2e2013-06-11 04:39:30256 break;
257 }
[email protected]9f39c202013-06-18 16:06:42258 case GL_COMPOSITOR_FRAME: {
[email protected]95d31822014-01-03 22:21:55259 FrameHostMsg_CompositorFrameSwappedACK_Params params;
260 params.producing_host_id = mailbox.host_id;
261 params.producing_route_id = mailbox.route_id;
262 params.output_surface_id = mailbox.output_surface_id;
263 params.ack.gl_frame_data.reset(new cc::GLFrameData());
264 params.ack.gl_frame_data->mailbox = mailbox.name;
265 params.ack.gl_frame_data->size = mailbox.size;
266 params.ack.gl_frame_data->sync_point = sync_point;
[email protected]bffc8302014-01-23 20:52:16267 SendCompositorFrameSwappedACKToBrowser(params);
[email protected]c049b2e2013-06-11 04:39:30268 break;
269 }
[email protected]9afdaef2013-09-26 07:24:37270 case SOFTWARE_COMPOSITOR_FRAME:
[email protected]9f39c202013-06-18 16:06:42271 break;
[email protected]c049b2e2013-06-11 04:39:30272 }
[email protected]0d25cb62013-01-21 15:42:21273}
274
[email protected]bffc8302014-01-23 20:52:16275void ChildFrameCompositingHelper::OnContainerDestroy() {
[email protected]94224ba62014-02-04 00:25:24276 if (GetContainer())
277 GetContainer()->setWebLayer(NULL);
[email protected]0d25cb62013-01-21 15:42:21278
[email protected]b0030b72013-11-15 20:35:53279 if (resource_collection_)
280 resource_collection_->SetClient(NULL);
281
[email protected]7873fe4e2013-11-14 18:35:22282 ack_pending_ = false;
283 software_ack_pending_ = false;
[email protected]b0030b72013-11-15 20:35:53284 resource_collection_ = NULL;
285 frame_provider_ = NULL;
[email protected]0d25cb62013-01-21 15:42:21286 texture_layer_ = NULL;
[email protected]f5b4b0f2013-04-02 18:16:28287 delegated_layer_ = NULL;
[email protected]396fbb72013-01-23 02:33:43288 background_layer_ = NULL;
[email protected]0d25cb62013-01-21 15:42:21289 web_layer_.reset();
290}
291
[email protected]f49722f2014-01-30 17:54:50292void ChildFrameCompositingHelper::ChildFrameGone() {
293 background_layer_->SetBackgroundColor(SkColorSetARGBInline(255, 0, 128, 0));
294 background_layer_->RemoveAllChildren();
295 background_layer_->SetIsDrawable(true);
296 background_layer_->SetContentsOpaque(true);
297}
298
[email protected]bffc8302014-01-23 20:52:16299void ChildFrameCompositingHelper::OnBuffersSwappedPrivate(
[email protected]9f39c202013-06-18 16:06:42300 const SwapBuffersInfo& mailbox,
[email protected]df41e252014-02-03 23:39:50301 uint32 sync_point,
[email protected]19fa81a02013-03-04 18:23:32302 float device_scale_factor) {
[email protected]fc72bb12013-06-02 21:13:46303 DCHECK(!delegated_layer_.get());
[email protected]4f7bbdc2013-01-29 02:31:39304 // If these mismatch, we are either just starting up, GPU process crashed or
305 // guest renderer crashed.
306 // In this case, we are communicating with a new image transport
307 // surface and must ACK with the new ID's and an empty mailbox.
[email protected]53b4cc12013-07-18 23:02:30308 if (last_route_id_ != mailbox.route_id ||
309 last_output_surface_id_ != mailbox.output_surface_id ||
310 last_host_id_ != mailbox.host_id)
[email protected]4f7bbdc2013-01-29 02:31:39311 last_mailbox_valid_ = false;
312
[email protected]c049b2e2013-06-11 04:39:30313 last_route_id_ = mailbox.route_id;
[email protected]53b4cc12013-07-18 23:02:30314 last_output_surface_id_ = mailbox.output_surface_id;
[email protected]c049b2e2013-06-11 04:39:30315 last_host_id_ = mailbox.host_id;
[email protected]4f7bbdc2013-01-29 02:31:39316
[email protected]0d25cb62013-01-21 15:42:21317 ack_pending_ = true;
318 // Browser plugin getting destroyed, do a fast ACK.
[email protected]fc72bb12013-06-02 21:13:46319 if (!background_layer_.get()) {
[email protected]c049b2e2013-06-11 04:39:30320 MailboxReleased(mailbox, sync_point, false);
[email protected]0d25cb62013-01-21 15:42:21321 return;
322 }
323
[email protected]fc72bb12013-06-02 21:13:46324 if (!texture_layer_.get()) {
[email protected]e8e4ae232013-04-12 00:26:01325 texture_layer_ = cc::TextureLayer::CreateForMailbox(NULL);
[email protected]f5b4b0f2013-04-02 18:16:28326 texture_layer_->SetIsDrawable(true);
[email protected]6d3a46e2013-11-25 23:08:53327 SetContentsOpaque(opaque_);
[email protected]f5b4b0f2013-04-02 18:16:28328
329 background_layer_->AddChild(texture_layer_);
330 }
331
[email protected]0d25cb62013-01-21 15:42:21332 // The size of browser plugin container is not always equal to the size
333 // of the buffer that arrives here. This could be for a number of reasons,
334 // including autosize and a resize in progress.
335 // During resize, the container size changes first and then some time
336 // later, a new buffer with updated size will arrive. During this process,
337 // we need to make sure that things are still displayed pixel perfect.
[email protected]396fbb72013-01-23 02:33:43338 // We accomplish this by modifying bounds of the texture layer only
339 // when a new buffer arrives.
340 // Visually, this will either display a smaller part of the buffer
341 // or introduce a gutter around it.
[email protected]bffc8302014-01-23 20:52:16342 CheckSizeAndAdjustLayerProperties(
343 mailbox.size, device_scale_factor, texture_layer_.get());
[email protected]0f21e8582013-01-11 11:06:56344
[email protected]9f39c202013-06-18 16:06:42345 bool is_software_frame = mailbox.type == SOFTWARE_COMPOSITOR_FRAME;
[email protected]bffc8302014-01-23 20:52:16346 bool current_mailbox_valid = is_software_frame ? mailbox.shared_memory != NULL
347 : !mailbox.name.IsZero();
[email protected]9f39c202013-06-18 16:06:42348 if (!is_software_frame && !last_mailbox_valid_) {
349 SwapBuffersInfo empty_info = mailbox;
350 empty_info.name.SetZero();
[email protected]c049b2e2013-06-11 04:39:30351 MailboxReleased(empty_info, 0, false);
[email protected]0d25cb62013-01-21 15:42:21352 if (!current_mailbox_valid)
353 return;
354 }
[email protected]c2bfe4e2013-01-16 01:10:20355
[email protected]9f39c202013-06-18 16:06:42356 cc::TextureMailbox texture_mailbox;
[email protected]9260757f2013-09-17 01:24:16357 scoped_ptr<cc::SingleReleaseCallback> release_callback;
[email protected]c2bfe4e2013-01-16 01:10:20358 if (current_mailbox_valid) {
[email protected]bffc8302014-01-23 20:52:16359 release_callback =
360 cc::SingleReleaseCallback::Create(
361 base::Bind(&ChildFrameCompositingHelper::MailboxReleased,
362 scoped_refptr<ChildFrameCompositingHelper>(this),
363 mailbox)).Pass();
[email protected]df41e252014-02-03 23:39:50364 if (is_software_frame) {
[email protected]9260757f2013-09-17 01:24:16365 texture_mailbox = cc::TextureMailbox(mailbox.shared_memory, mailbox.size);
[email protected]df41e252014-02-03 23:39:50366 } else {
367 texture_mailbox =
368 cc::TextureMailbox(mailbox.name, GL_TEXTURE_2D, sync_point);
369 }
[email protected]c2bfe4e2013-01-16 01:10:20370 }
[email protected]9f39c202013-06-18 16:06:42371
372 texture_layer_->SetFlipped(!is_software_frame);
[email protected]9260757f2013-09-17 01:24:16373 texture_layer_->SetTextureMailbox(texture_mailbox, release_callback.Pass());
[email protected]7aba6662013-03-12 10:17:34374 texture_layer_->SetNeedsDisplay();
[email protected]c2bfe4e2013-01-16 01:10:20375 last_mailbox_valid_ = current_mailbox_valid;
376}
377
[email protected]bffc8302014-01-23 20:52:16378void ChildFrameCompositingHelper::OnBuffersSwapped(
[email protected]c049b2e2013-06-11 04:39:30379 const gfx::Size& size,
[email protected]7c6c09e2014-02-15 00:16:17380 const gpu::Mailbox& mailbox,
[email protected]c049b2e2013-06-11 04:39:30381 int gpu_route_id,
382 int gpu_host_id,
383 float device_scale_factor) {
[email protected]9f39c202013-06-18 16:06:42384 SwapBuffersInfo swap_info;
[email protected]7c6c09e2014-02-15 00:16:17385 swap_info.name = mailbox;
[email protected]c049b2e2013-06-11 04:39:30386 swap_info.type = TEXTURE_IMAGE_TRANSPORT;
387 swap_info.size = size;
388 swap_info.route_id = gpu_route_id;
[email protected]53b4cc12013-07-18 23:02:30389 swap_info.output_surface_id = 0;
[email protected]c049b2e2013-06-11 04:39:30390 swap_info.host_id = gpu_host_id;
391 OnBuffersSwappedPrivate(swap_info, 0, device_scale_factor);
392}
393
[email protected]bffc8302014-01-23 20:52:16394void ChildFrameCompositingHelper::OnCompositorFrameSwapped(
[email protected]f5b4b0f2013-04-02 18:16:28395 scoped_ptr<cc::CompositorFrame> frame,
396 int route_id,
[email protected]53b4cc12013-07-18 23:02:30397 uint32 output_surface_id,
[email protected]f1970082014-04-09 04:29:56398 int host_id,
399 base::SharedMemoryHandle handle) {
[email protected]bffc8302014-01-23 20:52:16400
[email protected]c049b2e2013-06-11 04:39:30401 if (frame->gl_frame_data) {
[email protected]9f39c202013-06-18 16:06:42402 SwapBuffersInfo swap_info;
[email protected]c049b2e2013-06-11 04:39:30403 swap_info.name = frame->gl_frame_data->mailbox;
[email protected]9f39c202013-06-18 16:06:42404 swap_info.type = GL_COMPOSITOR_FRAME;
[email protected]c049b2e2013-06-11 04:39:30405 swap_info.size = frame->gl_frame_data->size;
406 swap_info.route_id = route_id;
[email protected]53b4cc12013-07-18 23:02:30407 swap_info.output_surface_id = output_surface_id;
[email protected]c049b2e2013-06-11 04:39:30408 swap_info.host_id = host_id;
409 OnBuffersSwappedPrivate(swap_info,
410 frame->gl_frame_data->sync_point,
411 frame->metadata.device_scale_factor);
412 return;
413 }
414
[email protected]9f39c202013-06-18 16:06:42415 if (frame->software_frame_data) {
416 cc::SoftwareFrameData* frame_data = frame->software_frame_data.get();
417
418 SwapBuffersInfo swap_info;
419 swap_info.type = SOFTWARE_COMPOSITOR_FRAME;
420 swap_info.size = frame_data->size;
421 swap_info.route_id = route_id;
[email protected]53b4cc12013-07-18 23:02:30422 swap_info.output_surface_id = output_surface_id;
[email protected]9f39c202013-06-18 16:06:42423 swap_info.host_id = host_id;
424 swap_info.software_frame_id = frame_data->id;
425
426 scoped_ptr<base::SharedMemory> shared_memory(
[email protected]f1970082014-04-09 04:29:56427 new base::SharedMemory(handle, true));
[email protected]9f39c202013-06-18 16:06:42428 const size_t size_in_bytes = 4 * frame_data->size.GetArea();
429 if (!shared_memory->Map(size_in_bytes)) {
[email protected]bffc8302014-01-23 20:52:16430 LOG(ERROR) << "Failed to map shared memory of size " << size_in_bytes;
[email protected]9f39c202013-06-18 16:06:42431 // Send ACK right away.
[email protected]9afdaef2013-09-26 07:24:37432 software_ack_pending_ = true;
[email protected]9f39c202013-06-18 16:06:42433 MailboxReleased(swap_info, 0, false);
[email protected]9afdaef2013-09-26 07:24:37434 DidCommitCompositorFrame();
[email protected]9f39c202013-06-18 16:06:42435 return;
436 }
437
438 swap_info.shared_memory = shared_memory.release();
[email protected]bffc8302014-01-23 20:52:16439 OnBuffersSwappedPrivate(swap_info, 0, frame->metadata.device_scale_factor);
[email protected]9afdaef2013-09-26 07:24:37440 software_ack_pending_ = true;
441 last_route_id_ = route_id;
442 last_output_surface_id_ = output_surface_id;
443 last_host_id_ = host_id;
[email protected]9f39c202013-06-18 16:06:42444 return;
445 }
446
[email protected]fc72bb12013-06-02 21:13:46447 DCHECK(!texture_layer_.get());
[email protected]f5b4b0f2013-04-02 18:16:28448
[email protected]09f67382013-10-09 21:03:45449 cc::DelegatedFrameData* frame_data = frame->delegated_frame_data.get();
[email protected]b0030b72013-11-15 20:35:53450 // Do nothing if we are getting destroyed or have no frame data.
451 if (!frame_data || !background_layer_)
[email protected]f5b4b0f2013-04-02 18:16:28452 return;
453
[email protected]09f67382013-10-09 21:03:45454 DCHECK(!frame_data->render_pass_list.empty());
455 cc::RenderPass* root_pass = frame_data->render_pass_list.back();
456 gfx::Size frame_size = root_pass->output_rect.size();
457
[email protected]317f17d2013-11-09 05:03:48458 if (last_route_id_ != route_id ||
459 last_output_surface_id_ != output_surface_id ||
460 last_host_id_ != host_id) {
461 // Resource ids are scoped by the output surface.
462 // If the originating output surface doesn't match the last one, it
463 // indicates the guest's output surface may have been recreated, in which
464 // case we should recreate the DelegatedRendererLayer, to avoid matching
465 // resources from the old one with resources from the new one which would
466 // have the same id.
467 frame_provider_ = NULL;
468
469 // Drop the cc::DelegatedFrameResourceCollection so that we will not return
470 // any resources from the old output surface with the new output surface id.
471 if (resource_collection_) {
[email protected]b0030b72013-11-15 20:35:53472 resource_collection_->SetClient(NULL);
473
474 if (resource_collection_->LoseAllResources())
475 SendReturnedDelegatedResources();
[email protected]317f17d2013-11-09 05:03:48476 resource_collection_ = NULL;
477 }
478 last_output_surface_id_ = output_surface_id;
479 last_route_id_ = route_id;
480 last_host_id_ = host_id;
481 }
[email protected]09f67382013-10-09 21:03:45482 if (!resource_collection_) {
483 resource_collection_ = new cc::DelegatedFrameResourceCollection;
[email protected]b0030b72013-11-15 20:35:53484 resource_collection_->SetClient(this);
[email protected]09f67382013-10-09 21:03:45485 }
486 if (!frame_provider_.get() || frame_provider_->frame_size() != frame_size) {
487 frame_provider_ = new cc::DelegatedFrameProvider(
488 resource_collection_.get(), frame->delegated_frame_data.Pass());
489 if (delegated_layer_.get())
490 delegated_layer_->RemoveFromParent();
491 delegated_layer_ =
[email protected]b59c1612013-12-04 00:56:49492 cc::DelegatedRendererLayer::Create(frame_provider_.get());
[email protected]09f67382013-10-09 21:03:45493 delegated_layer_->SetIsDrawable(true);
[email protected]6d3a46e2013-11-25 23:08:53494 SetContentsOpaque(opaque_);
[email protected]09f67382013-10-09 21:03:45495 background_layer_->AddChild(delegated_layer_);
496 } else {
497 frame_provider_->SetFrameData(frame->delegated_frame_data.Pass());
498 }
499
[email protected]6d3a46e2013-11-25 23:08:53500 CheckSizeAndAdjustLayerProperties(
[email protected]f5b4b0f2013-04-02 18:16:28501 frame_data->render_pass_list.back()->output_rect.size(),
502 frame->metadata.device_scale_factor,
503 delegated_layer_.get());
504
[email protected]f5b4b0f2013-04-02 18:16:28505 ack_pending_ = true;
506}
507
[email protected]bffc8302014-01-23 20:52:16508void ChildFrameCompositingHelper::UpdateVisibility(bool visible) {
[email protected]fc72bb12013-06-02 21:13:46509 if (texture_layer_.get())
[email protected]7aba6662013-03-12 10:17:34510 texture_layer_->SetIsDrawable(visible);
[email protected]fc72bb12013-06-02 21:13:46511 if (delegated_layer_.get())
[email protected]f5b4b0f2013-04-02 18:16:28512 delegated_layer_->SetIsDrawable(visible);
[email protected]69b79122013-02-14 19:16:45513}
514
[email protected]bffc8302014-01-23 20:52:16515void ChildFrameCompositingHelper::UnusedResourcesAreAvailable() {
[email protected]b0030b72013-11-15 20:35:53516 if (ack_pending_)
517 return;
518
519 SendReturnedDelegatedResources();
520}
521
[email protected]bffc8302014-01-23 20:52:16522void ChildFrameCompositingHelper::SendReturnedDelegatedResources() {
523 FrameHostMsg_ReclaimCompositorResources_Params params;
[email protected]b0030b72013-11-15 20:35:53524 if (resource_collection_)
[email protected]bffc8302014-01-23 20:52:16525 resource_collection_->TakeUnusedResourcesForChildCompositor(
526 &params.ack.resources);
527 DCHECK(!params.ack.resources.empty());
[email protected]b0030b72013-11-15 20:35:53528
[email protected]bffc8302014-01-23 20:52:16529 params.route_id = last_route_id_;
530 params.output_surface_id = last_output_surface_id_;
531 params.renderer_host_id = last_host_id_;
532 SendReclaimCompositorResourcesToBrowser(params);
[email protected]b0030b72013-11-15 20:35:53533}
534
[email protected]bffc8302014-01-23 20:52:16535void ChildFrameCompositingHelper::SetContentsOpaque(bool opaque) {
[email protected]6d3a46e2013-11-25 23:08:53536 opaque_ = opaque;
537
538 if (texture_layer_.get())
539 texture_layer_->SetContentsOpaque(opaque_);
540 if (delegated_layer_.get())
541 delegated_layer_->SetContentsOpaque(opaque_);
542}
543
[email protected]bffc8302014-01-23 20:52:16544void ChildFrameCompositingHelper::CopyFromCompositingSurfaceHasResult(
[email protected]73405fb2013-12-11 04:59:37545 int request_id,
546 gfx::Size dest_size,
547 scoped_ptr<cc::CopyOutputResult> result) {
548 scoped_ptr<SkBitmap> bitmap;
549 if (result && result->HasBitmap() && !result->size().IsEmpty())
550 bitmap = result->TakeBitmap();
551
552 SkBitmap resized_bitmap;
553 if (bitmap) {
[email protected]bffc8302014-01-23 20:52:16554 resized_bitmap =
555 skia::ImageOperations::Resize(*bitmap,
556 skia::ImageOperations::RESIZE_BEST,
557 dest_size.width(),
558 dest_size.height());
[email protected]73405fb2013-12-11 04:59:37559 }
[email protected]94224ba62014-02-04 00:25:24560 if (GetBrowserPluginManager()) {
561 GetBrowserPluginManager()->Send(
562 new BrowserPluginHostMsg_CopyFromCompositingSurfaceAck(
563 host_routing_id_, GetInstanceID(), request_id, resized_bitmap));
564 }
[email protected]73405fb2013-12-11 04:59:37565}
566
[email protected]0f21e8582013-01-11 11:06:56567} // namespace content