Commit 9b004a34 authored by jbauman@chromium.org's avatar jbauman@chromium.org

Make fullscreen pepper flash create a texture layer with software compositor

This switches it away from using the legacy 2D path and gets rid of a couple of copies.

BUG=269214,275200

Review URL: https://chromiumcodereview.appspot.com/23866006

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@222236 0039d316-1c4b-4281-b951-d872f2087c98
parent 66376ed6
...@@ -8,6 +8,8 @@ ...@@ -8,6 +8,8 @@
#include "base/debug/trace_event.h" #include "base/debug/trace_event.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/message_loop/message_loop.h" #include "base/message_loop/message_loop.h"
#include "cc/resources/texture_mailbox.h"
#include "content/public/renderer/render_thread.h"
#include "content/public/renderer/renderer_ppapi_host.h" #include "content/public/renderer/renderer_ppapi_host.h"
#include "content/renderer/pepper/common.h" #include "content/renderer/pepper/common.h"
#include "content/renderer/pepper/gfx_conversion.h" #include "content/renderer/pepper/gfx_conversion.h"
...@@ -187,8 +189,8 @@ PepperGraphics2DHost::PepperGraphics2DHost(RendererPpapiHost* host, ...@@ -187,8 +189,8 @@ PepperGraphics2DHost::PepperGraphics2DHost(RendererPpapiHost* host,
is_always_opaque_(false), is_always_opaque_(false),
scale_(1.0f), scale_(1.0f),
weak_ptr_factory_(this), weak_ptr_factory_(this),
is_running_in_process_(host->IsRunningInProcess()) { is_running_in_process_(host->IsRunningInProcess()),
} texture_mailbox_modified_(true) {}
PepperGraphics2DHost::~PepperGraphics2DHost() { PepperGraphics2DHost::~PepperGraphics2DHost() {
// Unbind from the instance when destroyed if we're still bound. // Unbind from the instance when destroyed if we're still bound.
...@@ -312,6 +314,8 @@ bool PepperGraphics2DHost::BindToInstance( ...@@ -312,6 +314,8 @@ bool PepperGraphics2DHost::BindToInstance(
new_instance->InvalidateRect(gfx::Rect()); new_instance->InvalidateRect(gfx::Rect());
} }
texture_mailbox_modified_ = true;
bound_instance_ = new_instance; bound_instance_ = new_instance;
return true; return true;
} }
...@@ -551,6 +555,37 @@ int32_t PepperGraphics2DHost::OnHostMsgReadImageData( ...@@ -551,6 +555,37 @@ int32_t PepperGraphics2DHost::OnHostMsgReadImageData(
return ReadImageData(image, &top_left) ? PP_OK : PP_ERROR_FAILED; return ReadImageData(image, &top_left) ? PP_OK : PP_ERROR_FAILED;
} }
void ReleaseCallback(scoped_ptr<base::SharedMemory> memory,
unsigned sync_point,
bool lost_resource) {}
bool PepperGraphics2DHost::PrepareTextureMailbox(cc::TextureMailbox* mailbox) {
if (!texture_mailbox_modified_)
return false;
// TODO(jbauman): Send image_data_ through mailbox to avoid copy.
gfx::Size pixel_image_size(image_data_->width(), image_data_->height());
int buffer_size = pixel_image_size.GetArea() * 4;
scoped_ptr<base::SharedMemory> memory =
RenderThread::Get()->HostAllocateSharedMemoryBuffer(buffer_size);
if (!memory || !memory->Map(buffer_size))
return false;
void* src = image_data_->Map();
memcpy(memory->memory(), src, buffer_size);
image_data_->Unmap();
base::SharedMemory* mem = memory.get();
*mailbox =
cc::TextureMailbox(mem,
pixel_image_size,
base::Bind(&ReleaseCallback, base::Passed(&memory)));
texture_mailbox_modified_ = false;
return true;
}
void PepperGraphics2DHost::AttachedToNewLayer() {
texture_mailbox_modified_ = true;
}
int32_t PepperGraphics2DHost::Flush(PP_Resource* old_image_data) { int32_t PepperGraphics2DHost::Flush(PP_Resource* old_image_data) {
bool done_replace_contents = false; bool done_replace_contents = false;
bool no_update_visible = true; bool no_update_visible = true;
...@@ -616,6 +651,7 @@ int32_t PepperGraphics2DHost::Flush(PP_Resource* old_image_data) { ...@@ -616,6 +651,7 @@ int32_t PepperGraphics2DHost::Flush(PP_Resource* old_image_data) {
} else { } else {
bound_instance_->InvalidateRect(op_rect); bound_instance_->InvalidateRect(op_rect);
} }
texture_mailbox_modified_ = true;
} }
} }
queued_operations_.clear(); queued_operations_.clear();
......
...@@ -16,6 +16,8 @@ ...@@ -16,6 +16,8 @@
#include "ppapi/host/resource_host.h" #include "ppapi/host/resource_host.h"
#include "third_party/WebKit/public/platform/WebCanvas.h" #include "third_party/WebKit/public/platform/WebCanvas.h"
namespace cc { class TextureMailbox; }
namespace gfx { namespace gfx {
class Point; class Point;
class Rect; class Rect;
...@@ -57,6 +59,9 @@ class CONTENT_EXPORT PepperGraphics2DHost ...@@ -57,6 +59,9 @@ class CONTENT_EXPORT PepperGraphics2DHost
const gfx::Rect& plugin_rect, const gfx::Rect& plugin_rect,
const gfx::Rect& paint_rect); const gfx::Rect& paint_rect);
bool PrepareTextureMailbox(cc::TextureMailbox* mailbox);
void AttachedToNewLayer();
// Notifications about the view's progress painting. See PluginInstance. // Notifications about the view's progress painting. See PluginInstance.
// These messages are used to send Flush callbacks to the plugin. // These messages are used to send Flush callbacks to the plugin.
void ViewWillInitiatePaint(); void ViewWillInitiatePaint();
...@@ -169,6 +174,8 @@ class CONTENT_EXPORT PepperGraphics2DHost ...@@ -169,6 +174,8 @@ class CONTENT_EXPORT PepperGraphics2DHost
bool is_running_in_process_; bool is_running_in_process_;
bool texture_mailbox_modified_;
friend class PepperGraphics2DHostTest; friend class PepperGraphics2DHostTest;
DISALLOW_COPY_AND_ASSIGN(PepperGraphics2DHost); DISALLOW_COPY_AND_ASSIGN(PepperGraphics2DHost);
}; };
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/callback_helpers.h" #include "base/callback_helpers.h"
#include "base/command_line.h"
#include "base/debug/trace_event.h" #include "base/debug/trace_event.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/memory/linked_ptr.h" #include "base/memory/linked_ptr.h"
...@@ -17,6 +18,7 @@ ...@@ -17,6 +18,7 @@
#include "base/time/time.h" #include "base/time/time.h"
#include "cc/layers/texture_layer.h" #include "cc/layers/texture_layer.h"
#include "content/common/content_constants_internal.h" #include "content/common/content_constants_internal.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/page_zoom.h" #include "content/public/common/page_zoom.h"
#include "content/public/renderer/content_renderer_client.h" #include "content/public/renderer/content_renderer_client.h"
#include "content/renderer/pepper/common.h" #include "content/renderer/pepper/common.h"
...@@ -526,11 +528,6 @@ PepperPluginInstanceImpl::PepperPluginInstanceImpl( ...@@ -526,11 +528,6 @@ PepperPluginInstanceImpl::PepperPluginInstanceImpl(
PepperPluginInstanceImpl::~PepperPluginInstanceImpl() { PepperPluginInstanceImpl::~PepperPluginInstanceImpl() {
DCHECK(!fullscreen_container_); DCHECK(!fullscreen_container_);
// Force-unbind any Graphics. In the case of Graphics2D, if the plugin
// leaks the graphics 2D, it may actually get cleaned up after our
// destruction, so we need its pointers to be up-to-date.
BindGraphics(pp_instance(), 0);
// Free all the plugin objects. This will automatically clear the back- // Free all the plugin objects. This will automatically clear the back-
// pointer from the NPObject so WebKit can't call into the plugin any more. // pointer from the NPObject so WebKit can't call into the plugin any more.
// //
...@@ -594,8 +591,11 @@ void PepperPluginInstanceImpl::Delete() { ...@@ -594,8 +591,11 @@ void PepperPluginInstanceImpl::Delete() {
fullscreen_container_->Destroy(); fullscreen_container_->Destroy();
fullscreen_container_ = NULL; fullscreen_container_ = NULL;
} }
bound_graphics_3d_ = NULL;
UpdateLayer(); // Force-unbind any Graphics. In the case of Graphics2D, if the plugin
// leaks the graphics 2D, it may actually get cleaned up after our
// destruction, so we need its pointers to be up-to-date.
BindGraphics(pp_instance(), 0);
container_ = NULL; container_ = NULL;
} }
...@@ -631,12 +631,21 @@ void PepperPluginInstanceImpl::InvalidateRect(const gfx::Rect& rect) { ...@@ -631,12 +631,21 @@ void PepperPluginInstanceImpl::InvalidateRect(const gfx::Rect& rect) {
else else
container_->invalidateRect(rect); container_->invalidateRect(rect);
} }
if (texture_layer_) {
if (rect.IsEmpty()) {
texture_layer_->SetNeedsDisplay();
} else {
texture_layer_->SetNeedsDisplayRect(rect);
}
}
} }
void PepperPluginInstanceImpl::ScrollRect(int dx, void PepperPluginInstanceImpl::ScrollRect(int dx,
int dy, int dy,
const gfx::Rect& rect) { const gfx::Rect& rect) {
if (fullscreen_container_) { if (texture_layer_) {
InvalidateRect(rect);
} else if (fullscreen_container_) {
fullscreen_container_->ScrollRect(dx, dy, rect); fullscreen_container_->ScrollRect(dx, dy, rect);
} else { } else {
if (full_frame_ && !IsViewAccelerated()) { if (full_frame_ && !IsViewAccelerated()) {
...@@ -1666,9 +1675,7 @@ void PepperPluginInstanceImpl::UpdateFlashFullscreenState( ...@@ -1666,9 +1675,7 @@ void PepperPluginInstanceImpl::UpdateFlashFullscreenState(
return; return;
} }
PPB_Graphics3D_Impl* graphics_3d = bound_graphics_3d_.get(); UpdateLayer();
if (graphics_3d)
UpdateLayer();
bool old_plugin_focus = PluginHasFocus(); bool old_plugin_focus = PluginHasFocus();
flash_fullscreen_ = flash_fullscreen; flash_fullscreen_ = flash_fullscreen;
...@@ -1808,13 +1815,18 @@ void PepperPluginInstanceImpl::UpdateLayer() { ...@@ -1808,13 +1815,18 @@ void PepperPluginInstanceImpl::UpdateLayer() {
PlatformContext3D* context = bound_graphics_3d_->platform_context(); PlatformContext3D* context = bound_graphics_3d_->platform_context();
context->GetBackingMailbox(&mailbox); context->GetBackingMailbox(&mailbox);
} }
bool want_layer = !mailbox.IsZero(); bool want_3d_layer = !mailbox.IsZero();
bool want_2d_layer = bound_graphics_2d_platform_ &&
CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableSoftwareCompositing);
bool want_layer = want_3d_layer || want_2d_layer;
if (want_layer == !!texture_layer_.get() && if ((want_layer == !!texture_layer_.get()) &&
(want_3d_layer == layer_is_hardware_) &&
layer_bound_to_fullscreen_ == !!fullscreen_container_) layer_bound_to_fullscreen_ == !!fullscreen_container_)
return; return;
if (texture_layer_.get()) { if (texture_layer_) {
if (!layer_bound_to_fullscreen_) if (!layer_bound_to_fullscreen_)
container_->setWebLayer(NULL); container_->setWebLayer(NULL);
else if (fullscreen_container_) else if (fullscreen_container_)
...@@ -1823,8 +1835,20 @@ void PepperPluginInstanceImpl::UpdateLayer() { ...@@ -1823,8 +1835,20 @@ void PepperPluginInstanceImpl::UpdateLayer() {
texture_layer_ = NULL; texture_layer_ = NULL;
} }
if (want_layer) { if (want_layer) {
DCHECK(bound_graphics_3d_.get()); bool opaque = false;
texture_layer_ = cc::TextureLayer::CreateForMailbox(NULL); if (want_3d_layer) {
DCHECK(bound_graphics_3d_.get());
texture_layer_ = cc::TextureLayer::CreateForMailbox(NULL);
opaque = bound_graphics_3d_->IsOpaque();
texture_layer_->SetTextureMailbox(
cc::TextureMailbox(mailbox, base::Bind(&IgnoreCallback), 0));
} else {
DCHECK(bound_graphics_2d_platform_);
texture_layer_ = cc::TextureLayer::CreateForMailbox(this);
bound_graphics_2d_platform_->AttachedToNewLayer();
opaque = bound_graphics_2d_platform_->IsAlwaysOpaque();
texture_layer_->SetFlipped(false);
}
web_layer_.reset(new webkit::WebLayerImpl(texture_layer_)); web_layer_.reset(new webkit::WebLayerImpl(texture_layer_));
if (fullscreen_container_) { if (fullscreen_container_) {
fullscreen_container_->SetLayer(web_layer_.get()); fullscreen_container_->SetLayer(web_layer_.get());
...@@ -1834,12 +1858,27 @@ void PepperPluginInstanceImpl::UpdateLayer() { ...@@ -1834,12 +1858,27 @@ void PepperPluginInstanceImpl::UpdateLayer() {
texture_layer_->SetContentsOpaque(true); texture_layer_->SetContentsOpaque(true);
} else { } else {
container_->setWebLayer(web_layer_.get()); container_->setWebLayer(web_layer_.get());
texture_layer_->SetContentsOpaque(bound_graphics_3d_->IsOpaque()); texture_layer_->SetContentsOpaque(opaque);
} }
texture_layer_->SetTextureMailbox(
cc::TextureMailbox(mailbox, base::Bind(&IgnoreCallback), 0));
} }
layer_bound_to_fullscreen_ = !!fullscreen_container_; layer_bound_to_fullscreen_ = !!fullscreen_container_;
layer_is_hardware_ = want_3d_layer;
}
unsigned PepperPluginInstanceImpl::PrepareTexture() {
return 0;
}
WebKit::WebGraphicsContext3D* PepperPluginInstanceImpl::Context3d() {
return NULL;
}
bool PepperPluginInstanceImpl::PrepareTextureMailbox(
cc::TextureMailbox* mailbox,
bool use_shared_memory) {
if (!bound_graphics_2d_platform_)
return false;
return bound_graphics_2d_platform_->PrepareTextureMailbox(mailbox);
} }
void PepperPluginInstanceImpl::AddPluginObject(PluginObject* plugin_object) { void PepperPluginInstanceImpl::AddPluginObject(PluginObject* plugin_object) {
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/strings/string16.h" #include "base/strings/string16.h"
#include "cc/layers/content_layer_client.h"
#include "cc/layers/texture_layer_client.h" #include "cc/layers/texture_layer_client.h"
#include "content/common/content_export.h" #include "content/common/content_export.h"
#include "content/public/renderer/pepper_plugin_instance.h" #include "content/public/renderer/pepper_plugin_instance.h"
...@@ -114,7 +115,8 @@ class CONTENT_EXPORT PepperPluginInstanceImpl ...@@ -114,7 +115,8 @@ class CONTENT_EXPORT PepperPluginInstanceImpl
: public base::RefCounted<PepperPluginInstanceImpl>, : public base::RefCounted<PepperPluginInstanceImpl>,
public base::SupportsWeakPtr<PepperPluginInstanceImpl>, public base::SupportsWeakPtr<PepperPluginInstanceImpl>,
public NON_EXPORTED_BASE(PepperPluginInstance), public NON_EXPORTED_BASE(PepperPluginInstance),
public ppapi::PPB_Instance_Shared { public ppapi::PPB_Instance_Shared,
public NON_EXPORTED_BASE(cc::TextureLayerClient) {
public: public:
// Create and return a PepperPluginInstanceImpl object which supports the most // Create and return a PepperPluginInstanceImpl object which supports the most
// recent version of PPP_Instance possible by querying the given // recent version of PPP_Instance possible by querying the given
...@@ -499,6 +501,12 @@ class CONTENT_EXPORT PepperPluginInstanceImpl ...@@ -499,6 +501,12 @@ class CONTENT_EXPORT PepperPluginInstanceImpl
// This is not inlined so as to avoid an unnecessary header include of v8.h. // This is not inlined so as to avoid an unnecessary header include of v8.h.
v8::Isolate* GetIsolate() const; v8::Isolate* GetIsolate() const;
// cc::TextureLayerClient implementation.
virtual unsigned PrepareTexture() OVERRIDE;
virtual WebKit::WebGraphicsContext3D* Context3d() OVERRIDE;
virtual bool PrepareTextureMailbox(cc::TextureMailbox* mailbox,
bool use_shared_memory) OVERRIDE;
private: private:
friend class base::RefCounted<PepperPluginInstanceImpl>; friend class base::RefCounted<PepperPluginInstanceImpl>;
friend class PpapiUnittest; friend class PpapiUnittest;
...@@ -661,6 +669,7 @@ class CONTENT_EXPORT PepperPluginInstanceImpl ...@@ -661,6 +669,7 @@ class CONTENT_EXPORT PepperPluginInstanceImpl
scoped_refptr<cc::TextureLayer> texture_layer_; scoped_refptr<cc::TextureLayer> texture_layer_;
scoped_ptr<WebKit::WebLayer> web_layer_; scoped_ptr<WebKit::WebLayer> web_layer_;
bool layer_bound_to_fullscreen_; bool layer_bound_to_fullscreen_;
bool layer_is_hardware_;
// Plugin URL. // Plugin URL.
GURL plugin_url_; GURL plugin_url_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment