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 @@
#include "base/debug/trace_event.h"
#include "base/logging.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/renderer/pepper/common.h"
#include "content/renderer/pepper/gfx_conversion.h"
......@@ -187,8 +189,8 @@ PepperGraphics2DHost::PepperGraphics2DHost(RendererPpapiHost* host,
is_always_opaque_(false),
scale_(1.0f),
weak_ptr_factory_(this),
is_running_in_process_(host->IsRunningInProcess()) {
}
is_running_in_process_(host->IsRunningInProcess()),
texture_mailbox_modified_(true) {}
PepperGraphics2DHost::~PepperGraphics2DHost() {
// Unbind from the instance when destroyed if we're still bound.
......@@ -312,6 +314,8 @@ bool PepperGraphics2DHost::BindToInstance(
new_instance->InvalidateRect(gfx::Rect());
}
texture_mailbox_modified_ = true;
bound_instance_ = new_instance;
return true;
}
......@@ -551,6 +555,37 @@ int32_t PepperGraphics2DHost::OnHostMsgReadImageData(
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) {
bool done_replace_contents = false;
bool no_update_visible = true;
......@@ -616,6 +651,7 @@ int32_t PepperGraphics2DHost::Flush(PP_Resource* old_image_data) {
} else {
bound_instance_->InvalidateRect(op_rect);
}
texture_mailbox_modified_ = true;
}
}
queued_operations_.clear();
......
......@@ -16,6 +16,8 @@
#include "ppapi/host/resource_host.h"
#include "third_party/WebKit/public/platform/WebCanvas.h"
namespace cc { class TextureMailbox; }
namespace gfx {
class Point;
class Rect;
......@@ -57,6 +59,9 @@ class CONTENT_EXPORT PepperGraphics2DHost
const gfx::Rect& plugin_rect,
const gfx::Rect& paint_rect);
bool PrepareTextureMailbox(cc::TextureMailbox* mailbox);
void AttachedToNewLayer();
// Notifications about the view's progress painting. See PluginInstance.
// These messages are used to send Flush callbacks to the plugin.
void ViewWillInitiatePaint();
......@@ -169,6 +174,8 @@ class CONTENT_EXPORT PepperGraphics2DHost
bool is_running_in_process_;
bool texture_mailbox_modified_;
friend class PepperGraphics2DHostTest;
DISALLOW_COPY_AND_ASSIGN(PepperGraphics2DHost);
};
......
......@@ -6,6 +6,7 @@
#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/command_line.h"
#include "base/debug/trace_event.h"
#include "base/logging.h"
#include "base/memory/linked_ptr.h"
......@@ -17,6 +18,7 @@
#include "base/time/time.h"
#include "cc/layers/texture_layer.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/renderer/content_renderer_client.h"
#include "content/renderer/pepper/common.h"
......@@ -526,11 +528,6 @@ PepperPluginInstanceImpl::PepperPluginInstanceImpl(
PepperPluginInstanceImpl::~PepperPluginInstanceImpl() {
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-
// pointer from the NPObject so WebKit can't call into the plugin any more.
//
......@@ -594,8 +591,11 @@ void PepperPluginInstanceImpl::Delete() {
fullscreen_container_->Destroy();
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;
}
......@@ -631,12 +631,21 @@ void PepperPluginInstanceImpl::InvalidateRect(const gfx::Rect& rect) {
else
container_->invalidateRect(rect);
}
if (texture_layer_) {
if (rect.IsEmpty()) {
texture_layer_->SetNeedsDisplay();
} else {
texture_layer_->SetNeedsDisplayRect(rect);
}
}
}
void PepperPluginInstanceImpl::ScrollRect(int dx,
int dy,
const gfx::Rect& rect) {
if (fullscreen_container_) {
if (texture_layer_) {
InvalidateRect(rect);
} else if (fullscreen_container_) {
fullscreen_container_->ScrollRect(dx, dy, rect);
} else {
if (full_frame_ && !IsViewAccelerated()) {
......@@ -1666,8 +1675,6 @@ void PepperPluginInstanceImpl::UpdateFlashFullscreenState(
return;
}
PPB_Graphics3D_Impl* graphics_3d = bound_graphics_3d_.get();
if (graphics_3d)
UpdateLayer();
bool old_plugin_focus = PluginHasFocus();
......@@ -1808,13 +1815,18 @@ void PepperPluginInstanceImpl::UpdateLayer() {
PlatformContext3D* context = bound_graphics_3d_->platform_context();
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_)
return;
if (texture_layer_.get()) {
if (texture_layer_) {
if (!layer_bound_to_fullscreen_)
container_->setWebLayer(NULL);
else if (fullscreen_container_)
......@@ -1823,8 +1835,20 @@ void PepperPluginInstanceImpl::UpdateLayer() {
texture_layer_ = NULL;
}
if (want_layer) {
bool opaque = false;
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_));
if (fullscreen_container_) {
fullscreen_container_->SetLayer(web_layer_.get());
......@@ -1834,12 +1858,27 @@ void PepperPluginInstanceImpl::UpdateLayer() {
texture_layer_->SetContentsOpaque(true);
} else {
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_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) {
......
......@@ -15,6 +15,7 @@
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/strings/string16.h"
#include "cc/layers/content_layer_client.h"
#include "cc/layers/texture_layer_client.h"
#include "content/common/content_export.h"
#include "content/public/renderer/pepper_plugin_instance.h"
......@@ -114,7 +115,8 @@ class CONTENT_EXPORT PepperPluginInstanceImpl
: public base::RefCounted<PepperPluginInstanceImpl>,
public base::SupportsWeakPtr<PepperPluginInstanceImpl>,
public NON_EXPORTED_BASE(PepperPluginInstance),
public ppapi::PPB_Instance_Shared {
public ppapi::PPB_Instance_Shared,
public NON_EXPORTED_BASE(cc::TextureLayerClient) {
public:
// Create and return a PepperPluginInstanceImpl object which supports the most
// recent version of PPP_Instance possible by querying the given
......@@ -499,6 +501,12 @@ class CONTENT_EXPORT PepperPluginInstanceImpl
// This is not inlined so as to avoid an unnecessary header include of v8.h.
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:
friend class base::RefCounted<PepperPluginInstanceImpl>;
friend class PpapiUnittest;
......@@ -661,6 +669,7 @@ class CONTENT_EXPORT PepperPluginInstanceImpl
scoped_refptr<cc::TextureLayer> texture_layer_;
scoped_ptr<WebKit::WebLayer> web_layer_;
bool layer_bound_to_fullscreen_;
bool layer_is_hardware_;
// 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