Index: content/renderer/browser_plugin/browser_plugin_compositing_helper.cc |
diff --git a/content/renderer/browser_plugin/browser_plugin_compositing_helper.cc b/content/renderer/browser_plugin/browser_plugin_compositing_helper.cc |
index dd7d84fc51a1b3e65cbcb4d13e53a24e79b05aec..c33b094c6ba1fcd3d3f6735249007f341ccc8b44 100644 |
--- a/content/renderer/browser_plugin/browser_plugin_compositing_helper.cc |
+++ b/content/renderer/browser_plugin/browser_plugin_compositing_helper.cc |
@@ -6,36 +6,28 @@ |
#include "cc/texture_layer.h" |
#include "content/common/browser_plugin_messages.h" |
+#include "content/renderer/browser_plugin/browser_plugin_manager.h" |
#include "content/renderer/render_thread_impl.h" |
+#include "third_party/khronos/GLES2/gl2.h" |
+#include "third_party/WebKit/Source/Platform/chromium/public/WebGraphicsContext3D.h" |
+#include "third_party/WebKit/Source/Platform/chromium/public/WebSharedGraphicsContext3D.h" |
#include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginContainer.h" |
#include "webkit/compositor_bindings/web_layer_impl.h" |
namespace content { |
-static void SendACK(const std::string& mailbox_name, |
- int host_route_id, |
- int gpu_route_id, |
- int gpu_host_id, |
- unsigned sync_point) { |
- RenderThread::Get()->Send( |
- new BrowserPluginHostMsg_BuffersSwappedACK( |
- host_route_id, |
- gpu_route_id, |
- gpu_host_id, |
- mailbox_name, |
- sync_point)); |
-} |
- |
BrowserPluginCompositingHelper::BrowserPluginCompositingHelper( |
WebKit::WebPluginContainer* container, |
+ BrowserPluginManager* manager, |
int host_routing_id) |
: host_routing_id_(host_routing_id), |
last_mailbox_valid_(false), |
- container_(container) { |
+ ack_pending_(true), |
+ container_(container), |
+ browser_plugin_manager_(manager) { |
} |
BrowserPluginCompositingHelper::~BrowserPluginCompositingHelper() { |
- container_->setWebLayer(NULL); |
} |
void BrowserPluginCompositingHelper::EnableCompositing(bool enable) { |
@@ -47,30 +39,99 @@ void BrowserPluginCompositingHelper::EnableCompositing(bool enable) { |
container_->setWebLayer(enable ? web_layer_.get() : NULL); |
} |
+// If we have a mailbox that was freed up from the compositor, |
+// but we are not expected to return it to the guest renderer |
+// via an ACK, we should free it because we now own it. |
+// To free the mailbox memory, we need a context to consume it |
+// into a texture ID and then delete this texture ID. |
+// We use a shared graphics context accessible from the main |
+// thread to do it. |
+void BrowserPluginCompositingHelper::FreeMailboxMemory( |
+ const std::string& mailbox_name, |
+ unsigned sync_point) { |
+ if (mailbox_name.empty()) |
+ return; |
+ |
+ WebKit::WebGraphicsContext3D *context = |
+ WebKit::WebSharedGraphicsContext3D::mainThreadContext(); |
+ DCHECK(context); |
+ if (sync_point) |
Fady Samuel
2013/01/18 18:57:01
This sync point represents when it's safe to consu
alexst (slow to review)
2013/01/18 19:15:42
Done.
|
+ context->waitSyncPoint(sync_point); |
+ |
+ unsigned texture_id = context->createTexture(); |
+ context->bindTexture(GL_TEXTURE_2D, texture_id); |
+ context->consumeTextureCHROMIUM( |
+ GL_TEXTURE_2D, |
+ reinterpret_cast<const int8*>(mailbox_name.data())); |
+ context->deleteTexture(texture_id); |
+} |
+ |
+void BrowserPluginCompositingHelper::MailboxReleased( |
+ const std::string& mailbox_name, |
+ int gpu_route_id, |
+ int gpu_host_id, |
+ unsigned sync_point) { |
+ // We need to send an ACK to TextureImageTransportSurface |
+ // for every buffer it sends us. However, if a buffer is freed up from |
+ // the compositor in cases like switching back to SW mode without a new |
+ // buffer arriving, no ACK is needed and we destroy this buffer. |
+ if (!ack_pending_) { |
+ FreeMailboxMemory(mailbox_name, sync_point); |
+ last_mailbox_valid_ = false; |
+ return; |
+ } |
+ ack_pending_ = false; |
+ browser_plugin_manager_->Send( |
+ new BrowserPluginHostMsg_BuffersSwappedACK( |
+ host_routing_id_, |
+ gpu_route_id, |
+ gpu_host_id, |
+ mailbox_name, |
+ sync_point)); |
+} |
+ |
+void BrowserPluginCompositingHelper::OnContainerDestroy() { |
+ if (container_) |
+ container_->setWebLayer(NULL); |
+ container_ = NULL; |
+ |
+ texture_layer_ = NULL; |
+ web_layer_.reset(); |
+} |
+ |
void BrowserPluginCompositingHelper::OnBuffersSwapped( |
const gfx::Size& size, |
const std::string& mailbox_name, |
int gpu_route_id, |
int gpu_host_id) { |
+ ack_pending_ = true; |
+ // Browser plugin getting destroyed, do a fast ACK. |
+ if (!texture_layer_) { |
+ MailboxReleased(mailbox_name, gpu_route_id, gpu_host_id, 0); |
+ return; |
+ } |
+ |
if (buffer_size_ != size) { |
Fady Samuel
2013/01/18 18:57:01
I realize this is already upstream but could you p
alexst (slow to review)
2013/01/18 19:15:42
Done.
|
buffer_size_ = size; |
UpdateUVRect(); |
} |
- if (!last_mailbox_valid_) |
- SendACK(std::string(), host_routing_id_, gpu_route_id, gpu_host_id, 0); |
bool current_mailbox_valid = !mailbox_name.empty(); |
- if (!current_mailbox_valid && !last_mailbox_valid_) |
- return; |
+ if (!last_mailbox_valid_) { |
+ MailboxReleased(std::string(), gpu_route_id, gpu_host_id, 0); |
+ if (!current_mailbox_valid) |
+ return; |
+ } |
cc::TextureLayer::MailboxCallback callback; |
if (current_mailbox_valid) { |
- callback = base::Bind(&SendACK, |
+ callback = base::Bind(&BrowserPluginCompositingHelper::MailboxReleased, |
+ scoped_refptr<BrowserPluginCompositingHelper>(this), |
mailbox_name, |
- host_routing_id_, |
gpu_route_id, |
gpu_host_id); |
} |
+ |
texture_layer_->setTextureMailbox(mailbox_name, callback); |
last_mailbox_valid_ = current_mailbox_valid; |
} |