diff options
21 files changed, 491 insertions, 32 deletions
diff --git a/content/content_tests.gypi b/content/content_tests.gypi index 84aea96..967bbc5 100644 --- a/content/content_tests.gypi +++ b/content/content_tests.gypi @@ -977,6 +977,7 @@ 'renderer/cpp_bound_class_unittest.cc', 'renderer/dom_serializer_browsertest.cc', 'renderer/mouse_lock_dispatcher_browsertest.cc', + 'renderer/pepper/fake_pepper_plugin_instance.cc', 'renderer/pepper/mock_renderer_ppapi_host.cc', 'renderer/pepper/pepper_device_enumeration_host_helper_unittest.cc', 'renderer/pepper/pepper_file_chooser_host_unittest.cc', diff --git a/content/renderer/pepper/fake_pepper_plugin_instance.cc b/content/renderer/pepper/fake_pepper_plugin_instance.cc new file mode 100644 index 0000000..72b992f --- /dev/null +++ b/content/renderer/pepper/fake_pepper_plugin_instance.cc @@ -0,0 +1,79 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/renderer/pepper/fake_pepper_plugin_instance.h" + +#include "ppapi/c/pp_errors.h" +#include "ppapi/shared_impl/ppapi_permissions.h" + +namespace content { + +FakePepperPluginInstance::~FakePepperPluginInstance() {} + +content::RenderView* FakePepperPluginInstance::GetRenderView() { + return NULL; +} + +blink::WebPluginContainer* FakePepperPluginInstance::GetContainer() { + return NULL; +} + +v8::Isolate* FakePepperPluginInstance::GetIsolate() const { + return NULL; +} + +ppapi::VarTracker* FakePepperPluginInstance::GetVarTracker() { + return NULL; +} + +const GURL& FakePepperPluginInstance::GetPluginURL() { + return gurl_; +} + +base::FilePath FakePepperPluginInstance::GetModulePath() { + return base::FilePath(); +} + +PP_Resource FakePepperPluginInstance::CreateImage(gfx::ImageSkia* source_image, + float scale) { + return 0; +} + +PP_ExternalPluginResult FakePepperPluginInstance::SwitchToOutOfProcessProxy( + const base::FilePath& file_path, + ppapi::PpapiPermissions permissions, + const IPC::ChannelHandle& channel_handle, + base::ProcessId plugin_pid, + int plugin_child_id) { + return PP_EXTERNAL_PLUGIN_FAILED; +} + +void FakePepperPluginInstance::SetAlwaysOnTop(bool on_top) {} + +bool FakePepperPluginInstance::IsFullPagePlugin() { + return false; +} + +bool FakePepperPluginInstance::FlashSetFullscreen(bool fullscreen, + bool delay_report) { + return false; +} + +bool FakePepperPluginInstance::IsRectTopmost(const gfx::Rect& rect) { + return false; +} + +int32_t FakePepperPluginInstance::Navigate( + const ppapi::URLRequestInfoData& request, + const char* target, + bool from_user_action) { + return PP_ERROR_FAILED; +} + +int FakePepperPluginInstance::MakePendingFileRefRendererHost( + const base::FilePath& path) { + return 0; +} + +} // namespace content diff --git a/content/renderer/pepper/fake_pepper_plugin_instance.h b/content/renderer/pepper/fake_pepper_plugin_instance.h new file mode 100644 index 0000000..bc50a7c --- /dev/null +++ b/content/renderer/pepper/fake_pepper_plugin_instance.h @@ -0,0 +1,48 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_RENDERER_PEPPER_FAKE_PEPPER_PLUGIN_INSTANCE_H_ +#define CONTENT_RENDERER_PEPPER_FAKE_PEPPER_PLUGIN_INSTANCE_H_ + +#include "content/public/renderer/pepper_plugin_instance.h" +#include "url/gurl.h" + +namespace content { + +class FakePepperPluginInstance : public PepperPluginInstance { + public: + virtual ~FakePepperPluginInstance(); + + // PepperPluginInstance overrides. + virtual content::RenderView* GetRenderView() OVERRIDE; + virtual blink::WebPluginContainer* GetContainer() OVERRIDE; + virtual v8::Isolate* GetIsolate() const OVERRIDE; + virtual ppapi::VarTracker* GetVarTracker() OVERRIDE; + virtual const GURL& GetPluginURL() OVERRIDE; + virtual base::FilePath GetModulePath() OVERRIDE; + virtual PP_Resource CreateImage(gfx::ImageSkia* source_image, + float scale) OVERRIDE; + virtual PP_ExternalPluginResult SwitchToOutOfProcessProxy( + const base::FilePath& file_path, + ppapi::PpapiPermissions permissions, + const IPC::ChannelHandle& channel_handle, + base::ProcessId plugin_pid, + int plugin_child_id) OVERRIDE; + virtual void SetAlwaysOnTop(bool on_top) OVERRIDE; + virtual bool IsFullPagePlugin() OVERRIDE; + virtual bool FlashSetFullscreen(bool fullscreen, bool delay_report) OVERRIDE; + virtual bool IsRectTopmost(const gfx::Rect& rect) OVERRIDE; + virtual int32_t Navigate(const ppapi::URLRequestInfoData& request, + const char* target, + bool from_user_action) OVERRIDE; + virtual int MakePendingFileRefRendererHost( + const base::FilePath& path) OVERRIDE; + + private: + GURL gurl_; +}; + +} // namespace content + +#endif // CONTENT_RENDERER_PEPPER_FAKE_PEPPER_PLUGIN_INSTANCE_H_ diff --git a/content/renderer/pepper/mock_renderer_ppapi_host.cc b/content/renderer/pepper/mock_renderer_ppapi_host.cc index 69a4e80..c54f404 100644 --- a/content/renderer/pepper/mock_renderer_ppapi_host.cc +++ b/content/renderer/pepper/mock_renderer_ppapi_host.cc @@ -4,6 +4,7 @@ #include "content/renderer/pepper/mock_renderer_ppapi_host.h" +#include "content/renderer/pepper/fake_pepper_plugin_instance.h" #include "ui/gfx/point.h" namespace content { @@ -14,7 +15,8 @@ MockRendererPpapiHost::MockRendererPpapiHost(RenderView* render_view, ppapi_host_(&sink_, ppapi::PpapiPermissions()), render_view_(render_view), pp_instance_(instance), - has_user_gesture_(false) { + has_user_gesture_(false), + plugin_instance_(new FakePepperPluginInstance) { } MockRendererPpapiHost::~MockRendererPpapiHost() { @@ -30,8 +32,7 @@ bool MockRendererPpapiHost::IsValidInstance(PP_Instance instance) const { PepperPluginInstance* MockRendererPpapiHost::GetPluginInstance( PP_Instance instance) const { - NOTIMPLEMENTED(); - return NULL; + return plugin_instance_.get(); } RenderView* MockRendererPpapiHost::GetRenderViewForInstance( @@ -74,7 +75,6 @@ IPC::PlatformFileForTransit MockRendererPpapiHost::ShareHandleWithRemote( } bool MockRendererPpapiHost::IsRunningInProcess() const { - NOTIMPLEMENTED(); return false; } diff --git a/content/renderer/pepper/mock_renderer_ppapi_host.h b/content/renderer/pepper/mock_renderer_ppapi_host.h index 2d534787..460a8c1 100644 --- a/content/renderer/pepper/mock_renderer_ppapi_host.h +++ b/content/renderer/pepper/mock_renderer_ppapi_host.h @@ -6,12 +6,14 @@ #define CONTENT_RENDERER_PEPPER_MOCK_RENDERER_PPAPI_HOST_H_ #include "base/basictypes.h" +#include "base/memory/scoped_ptr.h" #include "content/public/renderer/renderer_ppapi_host.h" #include "content/renderer/pepper/content_renderer_pepper_host_factory.h" #include "ppapi/host/ppapi_host.h" #include "ppapi/proxy/resource_message_test_sink.h" namespace content { +class FakePepperPluginInstance; class PluginModule; // A mock RendererPpapiHost for testing resource hosts. Messages sent by @@ -65,6 +67,8 @@ class MockRendererPpapiHost : public RendererPpapiHost { bool has_user_gesture_; + scoped_ptr<FakePepperPluginInstance> plugin_instance_; + DISALLOW_COPY_AND_ASSIGN(MockRendererPpapiHost); }; diff --git a/content/renderer/pepper/pepper_graphics_2d_host.cc b/content/renderer/pepper/pepper_graphics_2d_host.cc index f03f5cd..e55abac 100644 --- a/content/renderer/pepper/pepper_graphics_2d_host.cc +++ b/content/renderer/pepper/pepper_graphics_2d_host.cc @@ -27,7 +27,6 @@ #include "skia/ext/platform_canvas.h" #include "third_party/skia/include/core/SkBitmap.h" #include "ui/gfx/blit.h" -#include "ui/gfx/point.h" #include "ui/gfx/point_conversions.h" #include "ui/gfx/rect.h" #include "ui/gfx/rect_conversions.h" @@ -136,7 +135,8 @@ struct PepperGraphics2DHost::QueuedOperation { enum Type { PAINT, SCROLL, - REPLACE + REPLACE, + SET_OFFSET }; QueuedOperation(Type t) @@ -160,6 +160,9 @@ struct PepperGraphics2DHost::QueuedOperation { // Valid when type == REPLACE. scoped_refptr<PPB_ImageData_Impl> replace_image; + + // Valid when type == SET_OFFSET. + gfx::Point offset; }; // static @@ -240,6 +243,9 @@ int32_t PepperGraphics2DHost::OnResourceMessageReceived( PPAPI_DISPATCH_HOST_RESOURCE_CALL( PpapiHostMsg_Graphics2D_ReadImageData, OnHostMsgReadImageData) + PPAPI_DISPATCH_HOST_RESOURCE_CALL( + PpapiHostMsg_Graphics2D_SetOffset, + OnHostMsgSetOffset) IPC_END_MESSAGE_MAP() return PP_ERROR_FAILED; } @@ -390,6 +396,8 @@ void PepperGraphics2DHost::Paint(blink::WebCanvas* canvas, pixel_origin.scale(inverse_scale); canvas->scale(scale_, scale_); } + pixel_origin.offset(SkIntToScalar(plugin_offset_.x()), + SkIntToScalar(plugin_offset_.y())); canvas->drawBitmap(image, pixel_origin.x(), pixel_origin.y(), &paint); } @@ -420,6 +428,12 @@ PPB_ImageData_Impl* PepperGraphics2DHost::ImageData() { return image_data_.get(); } +gfx::Size PepperGraphics2DHost::Size() const { + if (!image_data_) + return gfx::Size(); + return gfx::Size(image_data_->width(), image_data_->height()); +} + int32_t PepperGraphics2DHost::OnHostMsgPaintImageData( ppapi::host::HostMessageContext* context, const ppapi::HostResource& image_data, @@ -549,6 +563,15 @@ int32_t PepperGraphics2DHost::OnHostMsgSetScale( return PP_ERROR_BADARGUMENT; } +int32_t PepperGraphics2DHost::OnHostMsgSetOffset( + ppapi::host::HostMessageContext* context, + const PP_Point& offset) { + QueuedOperation operation(QueuedOperation::SET_OFFSET); + operation.offset = PP_ToGfxPoint(offset); + queued_operations_.push_back(operation); + return PP_OK; +} + int32_t PepperGraphics2DHost::OnHostMsgReadImageData( ppapi::host::HostMessageContext* context, PP_Resource image, @@ -595,6 +618,7 @@ int32_t PepperGraphics2DHost::Flush(PP_Resource* old_image_data) { for (size_t i = 0; i < queued_operations_.size(); i++) { QueuedOperation& operation = queued_operations_[i]; gfx::Rect op_rect; + gfx::Rect old_op_rect; switch (operation.type) { case QueuedOperation::PAINT: ExecutePaintImageData(operation.paint_image.get(), @@ -618,16 +642,28 @@ int32_t PepperGraphics2DHost::Flush(PP_Resource* old_image_data) { done_replace_contents ? NULL : old_image_data); done_replace_contents = true; break; + case QueuedOperation::SET_OFFSET: + old_op_rect = gfx::Rect(plugin_offset_.x(), plugin_offset_.y(), + image_data_->width(), image_data_->height()); + plugin_offset_ = operation.offset; + // The offset is applied below for |op_rect|. + op_rect = gfx::Rect(image_data_->width(), image_data_->height()); + break; } + op_rect.Offset(plugin_offset_.x(), plugin_offset_.y()); + // For correctness with accelerated compositing, we must issue an invalidate // on the full op_rect even if it is partially or completely off-screen. // However, if we issue an invalidate for a clipped-out region, WebKit will // do nothing and we won't get any ViewFlushedPaint calls, leaving our // callback stranded. So we still need to check whether the repainted area // is visible to determine how to deal with the callback. - if (bound_instance_ && !op_rect.IsEmpty()) { + if (bound_instance_ && (!op_rect.IsEmpty() || !old_op_rect.IsEmpty())) { gfx::Point scroll_delta(operation.scroll_dx, operation.scroll_dy); + if (!ConvertToLogicalPixels(scale_, &old_op_rect, NULL)) { + NOTREACHED(); + } if (!ConvertToLogicalPixels(scale_, &op_rect, operation.type == QueuedOperation::SCROLL ? @@ -641,23 +677,31 @@ int32_t PepperGraphics2DHost::Flush(PP_Resource* old_image_data) { // Set |no_update_visible| to false if the change overlaps the visible // area. - gfx::Rect visible_changed_rect = gfx::IntersectRects(clip, op_rect); - if (!visible_changed_rect.IsEmpty()) + if (!gfx::IntersectRects(clip, op_rect).IsEmpty() || + !gfx::IntersectRects(clip, old_op_rect).IsEmpty()) { no_update_visible = false; + } // Notify the plugin of the entire change (op_rect), even if it is // partially or completely off-screen. if (operation.type == QueuedOperation::SCROLL) { bound_instance_->ScrollRect(scroll_delta.x(), scroll_delta.y(), op_rect); + DCHECK(old_op_rect.IsEmpty()); } else { - bound_instance_->InvalidateRect(op_rect); + if (!op_rect.IsEmpty()) + bound_instance_->InvalidateRect(op_rect); + if (!old_op_rect.IsEmpty()) + bound_instance_->InvalidateRect(old_op_rect); } texture_mailbox_modified_ = true; } } queued_operations_.clear(); + if (bound_instance_) + bound_instance_->UpdateLayerTransform(); + if (!bound_instance_) { // As promised in the API, we always schedule callback when unbound. ScheduleOffscreenFlushAck(); diff --git a/content/renderer/pepper/pepper_graphics_2d_host.h b/content/renderer/pepper/pepper_graphics_2d_host.h index 79b35e2..379826c 100644 --- a/content/renderer/pepper/pepper_graphics_2d_host.h +++ b/content/renderer/pepper/pepper_graphics_2d_host.h @@ -15,6 +15,8 @@ #include "ppapi/host/host_message_context.h" #include "ppapi/host/resource_host.h" #include "third_party/WebKit/public/platform/WebCanvas.h" +#include "ui/gfx/point.h" +#include "ui/gfx/size.h" namespace cc { class SingleReleaseCallback; @@ -22,7 +24,6 @@ class TextureMailbox; } namespace gfx { -class Point; class Rect; } @@ -78,6 +79,9 @@ class CONTENT_EXPORT PepperGraphics2DHost float GetScale() const; bool IsAlwaysOpaque() const; PPB_ImageData_Impl* ImageData(); + gfx::Size Size() const; + + gfx::Point plugin_offset() const { return plugin_offset_; } private: PepperGraphics2DHost(RendererPpapiHost* host, @@ -103,6 +107,8 @@ class CONTENT_EXPORT PepperGraphics2DHost int32_t OnHostMsgFlush(ppapi::host::HostMessageContext* context); int32_t OnHostMsgSetScale(ppapi::host::HostMessageContext* context, float scale); + int32_t OnHostMsgSetOffset(ppapi::host::HostMessageContext* context, + const PP_Point& offset); int32_t OnHostMsgReadImageData(ppapi::host::HostMessageContext* context, PP_Resource image, const PP_Point& top_left); @@ -147,7 +153,6 @@ class CONTENT_EXPORT PepperGraphics2DHost gfx::Rect* op_rect, gfx::Point* delta); - RendererPpapiHost* renderer_ppapi_host_; scoped_refptr<PPB_ImageData_Impl> image_data_; @@ -182,6 +187,11 @@ class CONTENT_EXPORT PepperGraphics2DHost bool is_running_in_process_; bool texture_mailbox_modified_; + bool is_using_texture_layer_; + + // The offset into the plugin area at which to draw the contents of the + // graphics context. + gfx::Point plugin_offset_; friend class PepperGraphics2DHostTest; DISALLOW_COPY_AND_ASSIGN(PepperGraphics2DHost); diff --git a/content/renderer/pepper/pepper_graphics_2d_host_unittest.cc b/content/renderer/pepper/pepper_graphics_2d_host_unittest.cc index 78a8fe0..28abbef 100644 --- a/content/renderer/pepper/pepper_graphics_2d_host_unittest.cc +++ b/content/renderer/pepper/pepper_graphics_2d_host_unittest.cc @@ -5,10 +5,19 @@ #include "content/renderer/pepper/pepper_graphics_2d_host.h" #include "base/basictypes.h" +#include "base/message_loop/message_loop.h" +#include "content/renderer/pepper/mock_renderer_ppapi_host.h" +#include "content/renderer/pepper/ppb_image_data_impl.h" +#include "ppapi/shared_impl/proxy_lock.h" +#include "ppapi/shared_impl/test_globals.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/WebKit/public/platform/WebCanvas.h" +#include "third_party/skia/include/core/SkCanvas.h" #include "ui/gfx/point.h" #include "ui/gfx/rect.h" +using blink::WebCanvas; + namespace content { class PepperGraphics2DHostTest : public testing::Test { @@ -18,6 +27,60 @@ class PepperGraphics2DHostTest : public testing::Test { gfx::Point* delta) { return PepperGraphics2DHost::ConvertToLogicalPixels(scale, op_rect, delta); } + + PepperGraphics2DHostTest() + : message_loop_(base::MessageLoop::TYPE_DEFAULT), + renderer_ppapi_host_(NULL, 12345) {} + + virtual ~PepperGraphics2DHostTest() { + ppapi::ProxyAutoLock proxy_lock; + host_.reset(); + } + + void Init(PP_Instance instance, + const PP_Size& backing_store_size, + const gfx::Rect& plugin_rect) { + test_globals_.GetResourceTracker()->DidCreateInstance(instance); + scoped_refptr<PPB_ImageData_Impl> backing_store( + new PPB_ImageData_Impl(instance, PPB_ImageData_Impl::ForTest())); + host_.reset(PepperGraphics2DHost::Create( + &renderer_ppapi_host_, instance, 12345, backing_store_size, PP_FALSE, + backing_store)); + DCHECK(host_.get()); + plugin_rect_ = plugin_rect; + } + + void PaintImageData(PPB_ImageData_Impl* image_data) { + ppapi::HostResource image_data_resource; + image_data_resource.SetHostResource(image_data->pp_instance(), + image_data->pp_resource()); + host_->OnHostMsgPaintImageData(NULL, image_data_resource, + PP_Point(), false, PP_Rect()); + } + + void SetOffset(const PP_Point& point) { + host_->OnHostMsgSetOffset(NULL, point); + } + + void Flush() { + ppapi::host::HostMessageContext context( + ppapi::proxy::ResourceMessageCallParams(host_->pp_resource(), 0)); + host_->OnHostMsgFlush(&context); + host_->ViewFlushedPaint(); + host_->SendOffscreenFlushAck(); + } + + void PaintToWebCanvas(WebCanvas* canvas) { + host_->Paint(canvas, plugin_rect_, + gfx::Rect(0, 0, plugin_rect_.width(), plugin_rect_.height())); + } + + private: + gfx::Rect plugin_rect_; + scoped_ptr<PepperGraphics2DHost> host_; + base::MessageLoop message_loop_; + MockRendererPpapiHost renderer_ppapi_host_; + ppapi::TestGlobals test_globals_; }; TEST_F(PepperGraphics2DHostTest, ConvertToLogicalPixels) { @@ -89,4 +152,77 @@ TEST_F(PepperGraphics2DHostTest, ConvertToLogicalPixels) { } } +TEST_F(PepperGraphics2DHostTest, SetOffset) { + ppapi::ProxyAutoLock proxy_lock; + + // Initialize the backing store. + PP_Instance instance = 12345; + PP_Size backing_store_size = { 300, 300 }; + gfx::Rect plugin_rect(0, 0, 500, 500); + Init(instance, backing_store_size, plugin_rect); + + // Paint the entire backing store red. + scoped_refptr<PPB_ImageData_Impl> image_data( + new PPB_ImageData_Impl(instance, PPB_ImageData_Impl::ForTest())); + image_data->Init(PPB_ImageData_Impl::GetNativeImageDataFormat(), + backing_store_size.width, + backing_store_size.height, + true); + { + ImageDataAutoMapper auto_mapper(image_data.get()); + image_data->GetMappedBitmap()->eraseColor( + SkColorSetARGBMacro(255, 255, 0, 0)); + } + PaintImageData(image_data.get()); + Flush(); + + // Set up the actual and expected bitmaps/canvas. + SkBitmap actual_bitmap; + actual_bitmap.setConfig(SkBitmap::kARGB_8888_Config, + plugin_rect.x() + plugin_rect.width(), + plugin_rect.y() + plugin_rect.height()); + actual_bitmap.allocPixels(); + actual_bitmap.eraseColor(0); + WebCanvas actual_canvas(actual_bitmap); + SkBitmap expected_bitmap; + expected_bitmap.setConfig(SkBitmap::kARGB_8888_Config, + plugin_rect.x() + plugin_rect.width(), + plugin_rect.y() + plugin_rect.height()); + expected_bitmap.allocPixels(); + expected_bitmap.eraseColor(0); + + // Paint the backing store to the canvas. + PaintToWebCanvas(&actual_canvas); + expected_bitmap.eraseArea( + SkIRect::MakeWH(backing_store_size.width, backing_store_size.height), + SkColorSetARGBMacro(255, 255, 0, 0)); + EXPECT_EQ(memcmp(expected_bitmap.getAddr(0, 0), + actual_bitmap.getAddr(0, 0), + expected_bitmap.getSize()), 0); + + // Set the offset. + PP_Point offset = { 20, 20 }; + SetOffset(offset); + actual_bitmap.eraseColor(0); + PaintToWebCanvas(&actual_canvas); + // No flush has occurred so the result should be the same. + EXPECT_EQ(memcmp(expected_bitmap.getAddr(0, 0), + actual_bitmap.getAddr(0, 0), + expected_bitmap.getSize()), 0); + + + // Flush the offset and the location of the rectangle should have shifted. + Flush(); + actual_bitmap.eraseColor(0); + PaintToWebCanvas(&actual_canvas); + expected_bitmap.eraseColor(0); + expected_bitmap.eraseArea( + SkIRect::MakeXYWH(offset.x, offset.y, + backing_store_size.width, backing_store_size.height), + SkColorSetARGBMacro(255, 255, 0, 0)); + EXPECT_EQ(memcmp(expected_bitmap.getAddr(0, 0), + actual_bitmap.getAddr(0, 0), + expected_bitmap.getSize()), 0); +} + } // namespace content diff --git a/content/renderer/pepper/pepper_plugin_instance_impl.cc b/content/renderer/pepper/pepper_plugin_instance_impl.cc index 6ff62cf..a36f0c3 100644 --- a/content/renderer/pepper/pepper_plugin_instance_impl.cc +++ b/content/renderer/pepper/pepper_plugin_instance_impl.cc @@ -111,9 +111,11 @@ #include "third_party/skia/include/core/SkRect.h" #include "ui/gfx/image/image_skia.h" #include "ui/gfx/image/image_skia_rep.h" +#include "ui/gfx/point_conversions.h" #include "ui/gfx/range/range.h" #include "ui/gfx/rect_conversions.h" #include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h" +#include "ui/gfx/size_conversions.h" #include "v8/include/v8.h" #include "webkit/renderer/compositor_bindings/web_layer_impl.h" @@ -1880,6 +1882,7 @@ void PepperPluginInstanceImpl::UpdateLayer() { } if (want_layer) { bool opaque = false; + scoped_refptr<cc::Layer> plugin_layer; if (want_3d_layer) { DCHECK(bound_graphics_3d_.get()); texture_layer_ = cc::TextureLayer::CreateForMailbox(NULL); @@ -1887,14 +1890,24 @@ void PepperPluginInstanceImpl::UpdateLayer() { texture_layer_->SetTextureMailbox( cc::TextureMailbox(mailbox, 0), cc::SingleReleaseCallback::Create(base::Bind(&IgnoreCallback))); + plugin_layer = texture_layer_; } 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); + texture_layer_->SetBounds(bound_graphics_2d_platform_->Size()); + texture_layer_->SetIsDrawable(true); + // WebLayer sets the bounds of its containing layer to be the same size as + // the plugin DOM element. Because we want to allow scaling/positioning of + // the layer in the 2D case (for SetOffset) we need to add this + // intermediate layer. If we wanted to support this functionality for the + // 3D case, we would need an intermediate layer in that case also. + plugin_layer = cc::Layer::Create(); + plugin_layer->AddChild(texture_layer_); } - web_layer_.reset(new webkit::WebLayerImpl(texture_layer_)); + web_layer_.reset(new webkit::WebLayerImpl(plugin_layer)); if (fullscreen_container_) { fullscreen_container_->SetLayer(web_layer_.get()); // Ignore transparency in fullscreen, since that's what Flash always @@ -1908,6 +1921,7 @@ void PepperPluginInstanceImpl::UpdateLayer() { } layer_bound_to_fullscreen_ = !!fullscreen_container_; layer_is_hardware_ = want_3d_layer; + UpdateLayerTransform(); } unsigned PepperPluginInstanceImpl::PrepareTexture() { @@ -1924,6 +1938,35 @@ bool PepperPluginInstanceImpl::PrepareTextureMailbox( mailbox, release_callback); } +void PepperPluginInstanceImpl::UpdateLayerTransform() { + if (!bound_graphics_2d_platform_ || !texture_layer_) { + // Currently the transform is only applied for Graphics2D. + return; + } + + // TODO(raymes): Get the scale from the Graphics2D host. + gfx::PointF scale(1.0f, 1.0f); + + gfx::RectF backing_store(bound_graphics_2d_platform_->plugin_offset(), + bound_graphics_2d_platform_->Size()); + backing_store = ScaleRect(backing_store, scale.x(), scale.y()); + + gfx::Rect layer_rect(ToEnclosingRect(backing_store)); + gfx::Size plugin_size(PP_ToGfxSize(view_data_.rect.size)); + layer_rect.Intersect(gfx::Rect(plugin_size)); + texture_layer_->SetPosition(layer_rect.origin()); + texture_layer_->SetBounds(layer_rect.size()); + + gfx::PointF u(PointAtOffsetFromOrigin( + layer_rect.origin() - backing_store.origin())); + gfx::PointF v(PointAtOffsetFromOrigin( + layer_rect.bottom_right() - backing_store.origin())); + gfx::RectF uv(BoundingRect(u, v)); + if (!backing_store.IsEmpty()) + uv.Scale(1.0f / backing_store.width(), 1.0f / backing_store.height()); + texture_layer_->SetUV(uv.origin(), uv.bottom_right()); +} + void PepperPluginInstanceImpl::AddPluginObject(PluginObject* plugin_object) { DCHECK(live_plugin_objects_.find(plugin_object) == live_plugin_objects_.end()); diff --git a/content/renderer/pepper/pepper_plugin_instance_impl.h b/content/renderer/pepper/pepper_plugin_instance_impl.h index 8285a6d..4d12f9b 100644 --- a/content/renderer/pepper/pepper_plugin_instance_impl.h +++ b/content/renderer/pepper/pepper_plugin_instance_impl.h @@ -503,6 +503,9 @@ class CONTENT_EXPORT PepperPluginInstanceImpl scoped_ptr<cc::SingleReleaseCallback>* release_callback, bool use_shared_memory) OVERRIDE; + // Update any transforms that should be applied to the texture layer. + void UpdateLayerTransform(); + private: friend class base::RefCounted<PepperPluginInstanceImpl>; friend class PpapiUnittest; @@ -596,8 +599,8 @@ class CONTENT_EXPORT PepperPluginInstanceImpl // Updates the layer for compositing. This creates a layer and attaches to the // container if: - // - we have a bound Graphics3D - // - the Graphics3D has a texture + // - we have a bound Graphics3D and the Graphics3D has a texture, OR + // we have a bound Graphics2D and are using software compositing // - we are not in Flash full-screen mode (or transitioning to it) // Otherwise it destroys the layer. // It does either operation lazily. diff --git a/ppapi/api/dev/ppb_graphics_2d_dev.idl b/ppapi/api/dev/ppb_graphics_2d_dev.idl index 33b5f59..2924760 100644 --- a/ppapi/api/dev/ppb_graphics_2d_dev.idl +++ b/ppapi/api/dev/ppb_graphics_2d_dev.idl @@ -8,7 +8,8 @@ [generate_thunk] label Chrome { - M22 = 0.1 + M22 = 0.1, + M32 = 0.2 }; /* PPB_Graphics2D_Dev interface */ @@ -45,5 +46,18 @@ interface PPB_Graphics2D_Dev { */ float_t GetScale( [in] PP_Resource resource); + + /*** + * Sets the offset into the plugin element at which the graphics context is + * painted. This allows a portion of the plugin element to be painted to. + * The new offset will only be applied after Flush() has been called. + * + * @param[in] resource A <code>Graphics2D</code> context resource. + * @param[in] offset The offset at which the context should be painted. + */ + [version=0.2] + void SetOffset( + [in] PP_Resource resource, + [in] PP_Point offset); }; diff --git a/ppapi/c/dev/ppb_graphics_2d_dev.h b/ppapi/c/dev/ppb_graphics_2d_dev.h index a4661215..789b6aa 100644 --- a/ppapi/c/dev/ppb_graphics_2d_dev.h +++ b/ppapi/c/dev/ppb_graphics_2d_dev.h @@ -3,18 +3,20 @@ * found in the LICENSE file. */ -/* From dev/ppb_graphics_2d_dev.idl modified Tue Jun 19 14:11:08 2012. */ +/* From dev/ppb_graphics_2d_dev.idl modified Wed Nov 6 16:07:44 2013. */ #ifndef PPAPI_C_DEV_PPB_GRAPHICS_2D_DEV_H_ #define PPAPI_C_DEV_PPB_GRAPHICS_2D_DEV_H_ #include "ppapi/c/pp_bool.h" #include "ppapi/c/pp_macros.h" +#include "ppapi/c/pp_point.h" #include "ppapi/c/pp_resource.h" #include "ppapi/c/pp_stdint.h" #define PPB_GRAPHICS2D_DEV_INTERFACE_0_1 "PPB_Graphics2D(Dev);0.1" -#define PPB_GRAPHICS2D_DEV_INTERFACE PPB_GRAPHICS2D_DEV_INTERFACE_0_1 +#define PPB_GRAPHICS2D_DEV_INTERFACE_0_2 "PPB_Graphics2D(Dev);0.2" +#define PPB_GRAPHICS2D_DEV_INTERFACE PPB_GRAPHICS2D_DEV_INTERFACE_0_2 /** * @file @@ -26,7 +28,7 @@ * @{ */ /* PPB_Graphics2D_Dev interface */ -struct PPB_Graphics2D_Dev_0_1 { +struct PPB_Graphics2D_Dev_0_2 { /** * SetScale() sets the scale factor that will be applied when painting the * graphics context onto the output device. Typically, if rendering at device @@ -55,9 +57,23 @@ struct PPB_Graphics2D_Dev_0_1 { * is not a valid <code>Graphics2D</code> context, this will return 0.0. */ float (*GetScale)(PP_Resource resource); + /*** + * Sets the offset into the plugin element at which the graphics context is + * painted. This allows a portion of the plugin element to be painted to. + * The new offset will only be applied after Flush() has been called. + * + * @param[in] resource A <code>Graphics2D</code> context resource. + * @param[in] offset The offset at which the context should be painted. + */ + void (*SetOffset)(PP_Resource resource, const struct PP_Point* offset); }; -typedef struct PPB_Graphics2D_Dev_0_1 PPB_Graphics2D_Dev; +typedef struct PPB_Graphics2D_Dev_0_2 PPB_Graphics2D_Dev; + +struct PPB_Graphics2D_Dev_0_1 { + PP_Bool (*SetScale)(PP_Resource resource, float scale); + float (*GetScale)(PP_Resource resource); +}; /** * @} */ diff --git a/ppapi/cpp/dev/graphics_2d_dev.cc b/ppapi/cpp/dev/graphics_2d_dev.cc index e141bb6..ee7a80f 100644 --- a/ppapi/cpp/dev/graphics_2d_dev.cc +++ b/ppapi/cpp/dev/graphics_2d_dev.cc @@ -6,33 +6,53 @@ #include "ppapi/c/dev/ppb_graphics_2d_dev.h" #include "ppapi/cpp/module_impl.h" +#include "ppapi/cpp/point.h" namespace pp { namespace { -template <> const char* interface_name<PPB_Graphics2D_Dev>() { - return PPB_GRAPHICS2D_DEV_INTERFACE; +template <> const char* interface_name<PPB_Graphics2D_Dev_0_1>() { + return PPB_GRAPHICS2D_DEV_INTERFACE_0_1; +} + +template <> const char* interface_name<PPB_Graphics2D_Dev_0_2>() { + return PPB_GRAPHICS2D_DEV_INTERFACE_0_2; } } // namespace // static bool Graphics2D_Dev::SupportsScale() { - return has_interface<PPB_Graphics2D_Dev>(); + return has_interface<PPB_Graphics2D_Dev_0_1>() || + has_interface<PPB_Graphics2D_Dev_0_2>(); } bool Graphics2D_Dev::SetScale(float scale) { - if (!has_interface<PPB_Graphics2D_Dev>()) - return false; - return PP_ToBool(get_interface<PPB_Graphics2D_Dev>()->SetScale(pp_resource(), - scale)); + if (has_interface<PPB_Graphics2D_Dev_0_2>()) { + return PP_ToBool(get_interface<PPB_Graphics2D_Dev_0_2>()->SetScale( + pp_resource(), scale)); + } + if (has_interface<PPB_Graphics2D_Dev_0_1>()) { + return PP_ToBool(get_interface<PPB_Graphics2D_Dev_0_1>()->SetScale( + pp_resource(), scale)); + } + return false; } float Graphics2D_Dev::GetScale() { - if (!has_interface<PPB_Graphics2D_Dev>()) - return 1.0f; - return get_interface<PPB_Graphics2D_Dev>()->GetScale(pp_resource()); + if (has_interface<PPB_Graphics2D_Dev_0_2>()) + return get_interface<PPB_Graphics2D_Dev_0_2>()->GetScale(pp_resource()); + if (has_interface<PPB_Graphics2D_Dev_0_1>()) + return get_interface<PPB_Graphics2D_Dev_0_1>()->GetScale(pp_resource()); + return 1.0f; +} + +void Graphics2D_Dev::SetOffset(const pp::Point& offset) { + if (!has_interface<PPB_Graphics2D_Dev_0_2>()) + return; + get_interface<PPB_Graphics2D_Dev_0_2>()->SetOffset(pp_resource(), + &offset.pp_point()); } } // namespace pp diff --git a/ppapi/cpp/dev/graphics_2d_dev.h b/ppapi/cpp/dev/graphics_2d_dev.h index 3dc8c71..d3a277b 100644 --- a/ppapi/cpp/dev/graphics_2d_dev.h +++ b/ppapi/cpp/dev/graphics_2d_dev.h @@ -9,6 +9,8 @@ namespace pp { +class Point; + // Graphics2DDev is a version of Graphics2D that exposes under-development APIs // for HiDPI class Graphics2D_Dev : public Graphics2D { @@ -48,6 +50,14 @@ class Graphics2D_Dev : public Graphics2D { /// @return Returns the scale factor for the graphics context. If the resource /// is invalid, 0.0 will be returned. float GetScale(); + + /// Set the offset into the plugin element at which the graphics context is + /// painted. This allows a portion of the plugin element to be painted to. + /// The new offset will only be applied after Flush() has been called. + /// + /// @param[in] resource A <code>Graphics2D</code> context resource. + /// @param[in] offset The offset at which the context should be painted. + void SetOffset(const pp::Point& offset); }; } // namespace pp diff --git a/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c b/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c index 98175e8..ff41829 100644 --- a/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c +++ b/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c @@ -1901,6 +1901,8 @@ static int32_t Pnacl_M14_PPB_Font_Dev_PixelOffsetForCharacter(PP_Resource font, /* Not generating wrapper methods for PPB_Graphics2D_Dev_0_1 */ +/* Not generating wrapper methods for PPB_Graphics2D_Dev_0_2 */ + /* Begin wrapper methods for PPB_IMEInputEvent_Dev_0_1 */ static PP_Bool Pnacl_M16_PPB_IMEInputEvent_Dev_IsIMEInputEvent(PP_Resource resource) { @@ -4615,6 +4617,8 @@ struct PPB_Font_Dev_0_6 Pnacl_Wrappers_PPB_Font_Dev_0_6 = { /* Not generating wrapper interface for PPB_Graphics2D_Dev_0_1 */ +/* Not generating wrapper interface for PPB_Graphics2D_Dev_0_2 */ + struct PPB_IMEInputEvent_Dev_0_1 Pnacl_Wrappers_PPB_IMEInputEvent_Dev_0_1 = { .IsIMEInputEvent = (PP_Bool (*)(PP_Resource resource))&Pnacl_M16_PPB_IMEInputEvent_Dev_IsIMEInputEvent, .GetText = (struct PP_Var (*)(PP_Resource ime_event))&Pnacl_M16_PPB_IMEInputEvent_Dev_GetText, diff --git a/ppapi/proxy/graphics_2d_resource.cc b/ppapi/proxy/graphics_2d_resource.cc index 3bad2e4e..cd7cf4f 100644 --- a/ppapi/proxy/graphics_2d_resource.cc +++ b/ppapi/proxy/graphics_2d_resource.cc @@ -111,6 +111,10 @@ float Graphics2DResource::GetScale() { return scale_; } +void Graphics2DResource::SetOffset(const PP_Point* offset) { + Post(RENDERER, PpapiHostMsg_Graphics2D_SetOffset(*offset)); +} + int32_t Graphics2DResource::Flush(scoped_refptr<TrackedCallback> callback) { // If host is not even created, return failure immediately. This can happen // when failed to initialize (in constructor). diff --git a/ppapi/proxy/graphics_2d_resource.h b/ppapi/proxy/graphics_2d_resource.h index b7ec30c..0fc3844 100644 --- a/ppapi/proxy/graphics_2d_resource.h +++ b/ppapi/proxy/graphics_2d_resource.h @@ -40,6 +40,7 @@ class PPAPI_PROXY_EXPORT Graphics2DResource virtual void ReplaceContents(PP_Resource image_data) OVERRIDE; virtual PP_Bool SetScale(float scale) OVERRIDE; virtual float GetScale() OVERRIDE; + virtual void SetOffset(const PP_Point* offset) OVERRIDE; virtual int32_t Flush(scoped_refptr<TrackedCallback> callback) OVERRIDE; virtual bool ReadImageData(PP_Resource image, const PP_Point* top_left) OVERRIDE; diff --git a/ppapi/proxy/ppapi_messages.h b/ppapi/proxy/ppapi_messages.h index daa9445..291851e 100644 --- a/ppapi/proxy/ppapi_messages.h +++ b/ppapi/proxy/ppapi_messages.h @@ -1363,6 +1363,8 @@ IPC_MESSAGE_CONTROL1(PpapiHostMsg_Graphics2D_ReplaceContents, ppapi::HostResource /* image_data */) IPC_MESSAGE_CONTROL1(PpapiHostMsg_Graphics2D_Dev_SetScale, float /* scale */) +IPC_MESSAGE_CONTROL1(PpapiHostMsg_Graphics2D_SetOffset, + PP_Point /* offset */) // Graphics2D, plugin -> host -> plugin IPC_MESSAGE_CONTROL0(PpapiHostMsg_Graphics2D_Flush) @@ -1386,7 +1388,6 @@ IPC_MESSAGE_CONTROL1(PpapiPluginMsg_NetworkMonitor_NetworkList, ppapi::proxy::SerializedNetworkList /* network_list */) IPC_MESSAGE_CONTROL0(PpapiPluginMsg_NetworkMonitor_Forbidden) - // NetworkProxy ---------------------------------------------------------------- IPC_MESSAGE_CONTROL0(PpapiHostMsg_NetworkProxy_Create) diff --git a/ppapi/thunk/interfaces_ppb_public_dev.h b/ppapi/thunk/interfaces_ppb_public_dev.h index d07f5dc..1ad85bc 100644 --- a/ppapi/thunk/interfaces_ppb_public_dev.h +++ b/ppapi/thunk/interfaces_ppb_public_dev.h @@ -68,6 +68,8 @@ PROXIED_IFACE(NoAPIName, PPB_CRYPTO_DEV_INTERFACE_0_1, PPB_Crypto_Dev_0_1) PROXIED_IFACE(NoAPIName, PPB_DEVICEREF_DEV_INTERFACE_0_1, PPB_DeviceRef_Dev_0_1) PROXIED_IFACE(NoAPIName, PPB_GRAPHICS2D_DEV_INTERFACE_0_1, PPB_Graphics2D_Dev_0_1) +PROXIED_IFACE(NoAPIName, PPB_GRAPHICS2D_DEV_INTERFACE_0_2, + PPB_Graphics2D_Dev_0_2) PROXIED_IFACE(PPB_Instance, PPB_CHAR_SET_DEV_INTERFACE_0_4, PPB_CharSet_Dev_0_4) PROXIED_IFACE(PPB_Instance, PPB_URLUTIL_DEV_INTERFACE_0_6, PPB_URLUtil_Dev_0_6) PROXIED_IFACE(PPB_Instance, PPB_URLUTIL_DEV_INTERFACE_0_7, PPB_URLUtil_Dev_0_7) diff --git a/ppapi/thunk/ppb_graphics_2d_api.h b/ppapi/thunk/ppb_graphics_2d_api.h index 4e1bda3..300aefe 100644 --- a/ppapi/thunk/ppb_graphics_2d_api.h +++ b/ppapi/thunk/ppb_graphics_2d_api.h @@ -36,6 +36,7 @@ class PPAPI_THUNK_EXPORT PPB_Graphics2D_API { // Dev interface. virtual PP_Bool SetScale(float scale) = 0; virtual float GetScale() = 0; + virtual void SetOffset(const PP_Point* offset) = 0; // Test only virtual bool ReadImageData(PP_Resource image, const PP_Point* top_left) = 0; diff --git a/ppapi/thunk/ppb_graphics_2d_dev_thunk.cc b/ppapi/thunk/ppb_graphics_2d_dev_thunk.cc index 760ecee..f178074 100644 --- a/ppapi/thunk/ppb_graphics_2d_dev_thunk.cc +++ b/ppapi/thunk/ppb_graphics_2d_dev_thunk.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// From dev/ppb_graphics_2d_dev.idl modified Fri Apr 26 08:52:02 2013. +// From dev/ppb_graphics_2d_dev.idl modified Wed Oct 2 17:27:31 2013. #include "ppapi/c/dev/ppb_graphics_2d_dev.h" #include "ppapi/c/pp_errors.h" @@ -34,16 +34,34 @@ float GetScale(PP_Resource resource) { return enter.object()->GetScale(); } +void SetOffset(PP_Resource resource, const struct PP_Point* offset) { + VLOG(4) << "PPB_Graphics2D_Dev::SetOffset()"; + EnterResource<PPB_Graphics2D_API> enter(resource, true); + if (enter.failed()) + return; + enter.object()->SetOffset(offset); +} + const PPB_Graphics2D_Dev_0_1 g_ppb_graphics2d_dev_thunk_0_1 = { &SetScale, &GetScale }; +const PPB_Graphics2D_Dev_0_2 g_ppb_graphics2d_dev_thunk_0_2 = { + &SetScale, + &GetScale, + &SetOffset +}; + } // namespace const PPB_Graphics2D_Dev_0_1* GetPPB_Graphics2D_Dev_0_1_Thunk() { return &g_ppb_graphics2d_dev_thunk_0_1; } +const PPB_Graphics2D_Dev_0_2* GetPPB_Graphics2D_Dev_0_2_Thunk() { + return &g_ppb_graphics2d_dev_thunk_0_2; +} + } // namespace thunk } // namespace ppapi |