Commit 75dae500 authored by sail@chromium.org's avatar sail@chromium.org

Mac Flash: Fix scaling bitmap

There was a bug in the Flash code that caused a render crash. To reproduce the crash you had to do the following:
  - run on a Retina device
  - disable accelerated compositing
  - enable click to play
In this case playing a flash video would crash the renderer.

The problem was that we were incorrectly calculating the scaled rect of a bitmap.

For example, when the pixel size of the bitmap is 1x1 the scaled size should be 0x0. Instead we were rounding up and returning a scaled valeu of 1x1.

Fix was to use ToEnclosedRect instead of ToEnclosingRect.

BUG=155309
TBR=brettw@chromium.org

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@162384 0039d316-1c4b-4281-b951-d872f2087c98
parent 4ef18aaa
// Copyright (c) 2012 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 "webkit/plugins/ppapi/mock_platform_image_2d.h"
#include "skia/ext/platform_canvas.h"
namespace webkit {
namespace ppapi {
MockPlatformImage2D::MockPlatformImage2D(int width, int height)
: width_(width),
height_(height) {
}
MockPlatformImage2D::~MockPlatformImage2D() {
}
skia::PlatformCanvas* MockPlatformImage2D::Map() {
return new skia::PlatformCanvas(width_, height_, true);
}
intptr_t MockPlatformImage2D::GetSharedMemoryHandle(uint32* byte_count) const {
*byte_count = 0;
return 0;
}
TransportDIB* MockPlatformImage2D::GetTransportDIB() const {
return NULL;
}
} // namespace ppapi
} // namespace webkit
// Copyright (c) 2012 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 WEBKIT_PLUGINS_PPAPI_MOCK_PLATFORM_IMAGE_2D_H_
#define WEBKIT_PLUGINS_PPAPI_MOCK_PLATFORM_IMAGE_2D_H_
#include "webkit/plugins/ppapi/plugin_delegate.h"
namespace webkit {
namespace ppapi {
class MockPlatformImage2D : public PluginDelegate::PlatformImage2D {
public:
MockPlatformImage2D(int width, int height);
virtual ~MockPlatformImage2D();
// PlatformImage2D implementation.
virtual skia::PlatformCanvas* Map() OVERRIDE;
virtual intptr_t GetSharedMemoryHandle(uint32* byte_count) const OVERRIDE;
virtual TransportDIB* GetTransportDIB() const OVERRIDE;
private:
int width_;
int height_;
};
} // namespace ppapi
} // namespace webkit
#endif // WEBKIT_PLUGINS_PPAPI_MOCK_PLATFORM_IMAGE_2D_H_
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "ppapi/c/pp_errors.h" #include "ppapi/c/pp_errors.h"
#include "ppapi/shared_impl/ppapi_preferences.h" #include "ppapi/shared_impl/ppapi_preferences.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebGamepads.h" #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebGamepads.h"
#include "webkit/plugins/ppapi/mock_platform_image_2d.h"
#include "webkit/plugins/ppapi/ppapi_plugin_instance.h" #include "webkit/plugins/ppapi/ppapi_plugin_instance.h"
namespace webkit { namespace webkit {
...@@ -73,7 +74,7 @@ WebKit::WebPlugin* MockPluginDelegate::CreatePluginReplacement( ...@@ -73,7 +74,7 @@ WebKit::WebPlugin* MockPluginDelegate::CreatePluginReplacement(
MockPluginDelegate::PlatformImage2D* MockPluginDelegate::CreateImage2D( MockPluginDelegate::PlatformImage2D* MockPluginDelegate::CreateImage2D(
int width, int width,
int height) { int height) {
return NULL; return new MockPlatformImage2D(width, height);
} }
MockPluginDelegate::PlatformContext3D* MockPluginDelegate::CreateContext3D() { MockPluginDelegate::PlatformContext3D* MockPluginDelegate::CreateContext3D() {
......
...@@ -1047,7 +1047,7 @@ bool PluginInstance::GetBitmapForOptimizedPluginPaint( ...@@ -1047,7 +1047,7 @@ bool PluginInstance::GetBitmapForOptimizedPluginPaint(
0, 0, image_data->width(), image_data->height()); 0, 0, image_data->width(), image_data->height());
float scale = GetBoundGraphics2D()->GetScale(); float scale = GetBoundGraphics2D()->GetScale();
gfx::Rect plugin_backing_store_rect = gfx::Rect plugin_backing_store_rect =
gfx::ToEnclosingRect(pixel_plugin_backing_store_rect.Scale(scale)); gfx::ToEnclosedRect(pixel_plugin_backing_store_rect.Scale(scale));
gfx::Rect clip_page = PP_ToGfxRect(view_data_.clip_rect); gfx::Rect clip_page = PP_ToGfxRect(view_data_.clip_rect);
gfx::Rect plugin_paint_rect = plugin_backing_store_rect.Intersect(clip_page); gfx::Rect plugin_paint_rect = plugin_backing_store_rect.Intersect(clip_page);
......
...@@ -493,6 +493,8 @@ class WEBKIT_PLUGINS_EXPORT PluginInstance : ...@@ -493,6 +493,8 @@ class WEBKIT_PLUGINS_EXPORT PluginInstance :
bool ResetAsProxied(scoped_refptr<PluginModule> module); bool ResetAsProxied(scoped_refptr<PluginModule> module);
private: private:
friend class PpapiUnittest;
// Implements PPB_Gamepad_API. This is just to avoid having an excessive // Implements PPB_Gamepad_API. This is just to avoid having an excessive
// number of interfaces implemented by PluginInstance. // number of interfaces implemented by PluginInstance.
class GamepadImpl : public ::ppapi::thunk::PPB_Gamepad_API { class GamepadImpl : public ::ppapi::thunk::PPB_Gamepad_API {
......
...@@ -7,10 +7,12 @@ ...@@ -7,10 +7,12 @@
#include "ppapi/c/pp_var.h" #include "ppapi/c/pp_var.h"
#include "ppapi/c/ppp_instance.h" #include "ppapi/c/ppp_instance.h"
#include "ppapi/shared_impl/ppapi_permissions.h" #include "ppapi/shared_impl/ppapi_permissions.h"
#include "webkit/plugins/ppapi/gfx_conversion.h"
#include "webkit/plugins/ppapi/mock_plugin_delegate.h" #include "webkit/plugins/ppapi/mock_plugin_delegate.h"
#include "webkit/plugins/ppapi/plugin_module.h" #include "webkit/plugins/ppapi/plugin_module.h"
#include "webkit/plugins/ppapi/ppapi_interface_factory.h" #include "webkit/plugins/ppapi/ppapi_interface_factory.h"
#include "webkit/plugins/ppapi/ppapi_plugin_instance.h" #include "webkit/plugins/ppapi/ppapi_plugin_instance.h"
#include "webkit/plugins/ppapi/ppb_graphics_2d_impl.h"
namespace webkit { namespace webkit {
namespace ppapi { namespace ppapi {
...@@ -85,7 +87,6 @@ void PpapiUnittest::SetUp() { ...@@ -85,7 +87,6 @@ void PpapiUnittest::SetUp() {
// Initialize the mock instance. // Initialize the mock instance.
instance_ = PluginInstance::Create(delegate_.get(), module()); instance_ = PluginInstance::Create(delegate_.get(), module());
} }
void PpapiUnittest::TearDown() { void PpapiUnittest::TearDown() {
...@@ -110,6 +111,12 @@ void PpapiUnittest::ShutdownModule() { ...@@ -110,6 +111,12 @@ void PpapiUnittest::ShutdownModule() {
module_ = NULL; module_ = NULL;
} }
void PpapiUnittest::SetViewSize(int width, int height, float scale) const {
instance_->view_data_.rect = PP_FromGfxRect(gfx::Rect(0, 0, width, height));
instance_->view_data_.clip_rect = instance_->view_data_.rect;
instance_->GetBoundGraphics2D()->SetScale(scale);
}
void PpapiUnittest::PluginModuleDead(PluginModule* /* dead_module */) { void PpapiUnittest::PluginModuleDead(PluginModule* /* dead_module */) {
// Nothing needed (this is necessary to make the module compile). // Nothing needed (this is necessary to make the module compile).
} }
......
...@@ -38,6 +38,9 @@ class PpapiUnittest : public testing::Test, ...@@ -38,6 +38,9 @@ class PpapiUnittest : public testing::Test,
// Deletes the instance and module to simulate module shutdown. // Deletes the instance and module to simulate module shutdown.
void ShutdownModule(); void ShutdownModule();
// Sets the view size of the plugin instance.
void SetViewSize(int width, int height, float scale) const;
protected: protected:
virtual MockPluginDelegate* NewPluginDelegate(); virtual MockPluginDelegate* NewPluginDelegate();
......
...@@ -33,9 +33,9 @@ class PPB_Graphics2D_Impl : public ::ppapi::Resource, ...@@ -33,9 +33,9 @@ class PPB_Graphics2D_Impl : public ::ppapi::Resource,
public: public:
virtual ~PPB_Graphics2D_Impl(); virtual ~PPB_Graphics2D_Impl();
static PP_Resource Create(PP_Instance instance, WEBKIT_PLUGINS_EXPORT static PP_Resource Create(PP_Instance instance,
const PP_Size& size, const PP_Size& size,
PP_Bool is_always_opaque); PP_Bool is_always_opaque);
bool is_always_opaque() const { return is_always_opaque_; } bool is_always_opaque() const { return is_always_opaque_; }
......
...@@ -6,9 +6,17 @@ ...@@ -6,9 +6,17 @@
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/point.h" #include "ui/gfx/point.h"
#include "ui/gfx/rect.h" #include "ui/gfx/rect.h"
#include "ui/gfx/safe_integer_conversions.h"
#include "webkit/plugins/ppapi/ppapi_unittest.h"
#include "webkit/plugins/ppapi/ppapi_plugin_instance.h"
#include "webkit/plugins/ppapi/ppb_graphics_2d_impl.h" #include "webkit/plugins/ppapi/ppb_graphics_2d_impl.h"
TEST(PpapiGraphics2DImplTest, ConvertToLogicalPixels) { namespace webkit {
namespace ppapi {
typedef PpapiUnittest PpapiGraphics2DImplTest;
TEST_F(PpapiGraphics2DImplTest, ConvertToLogicalPixels) {
static const struct { static const struct {
int x1; int x1;
int y1; int y1;
...@@ -78,3 +86,39 @@ TEST(PpapiGraphics2DImplTest, ConvertToLogicalPixels) { ...@@ -78,3 +86,39 @@ TEST(PpapiGraphics2DImplTest, ConvertToLogicalPixels) {
EXPECT_TRUE(r1.Contains(orig)); EXPECT_TRUE(r1.Contains(orig));
} }
} }
// Test that GetBitmapForOptimizedPluginPaint doesn't return a bitmap rect
// that's bigger than the actual backing store bitmap.
TEST_F(PpapiGraphics2DImplTest, GetBitmap2xScale) {
PP_Size size;
size.width = 3;
size.height = 3;
PP_Resource resource =
PPB_Graphics2D_Impl::Create(instance()->pp_instance(), size, PP_TRUE);
EXPECT_TRUE(resource);
EXPECT_TRUE(instance()->BindGraphics(instance()->pp_instance(), resource));
instance()->set_always_on_top(true);
float scale = 2.0;
SetViewSize(size.width, size.height, 1.0 / scale);
gfx::Rect bounds(0, 0, 1, 1);
gfx::Rect location;
gfx::Rect clip;
float bitmap_scale = 0;
TransportDIB* dib = NULL;
EXPECT_TRUE(instance()->GetBitmapForOptimizedPluginPaint(
bounds, &dib, &location, &clip, &bitmap_scale));
EXPECT_EQ(0, location.x());
EXPECT_EQ(0, location.y());
EXPECT_EQ(gfx::ToFlooredInt(size.width / scale), location.width());
EXPECT_EQ(gfx::ToFlooredInt(size.height / scale), location.height());
EXPECT_EQ(0, clip.x());
EXPECT_EQ(0, clip.y());
EXPECT_EQ(size.width, clip.width());
EXPECT_EQ(size.height, clip.height());
EXPECT_EQ(scale, bitmap_scale);
}
} // namespace ppapi
} // namespace webkit
...@@ -384,6 +384,8 @@ ...@@ -384,6 +384,8 @@
'../../mocks/mock_weburlloader.cc', '../../mocks/mock_weburlloader.cc',
'../../mocks/mock_weburlloader.h', '../../mocks/mock_weburlloader.h',
'../../plugins/ppapi/host_var_tracker_unittest.cc', '../../plugins/ppapi/host_var_tracker_unittest.cc',
'../../plugins/ppapi/mock_platform_image_2d.cc',
'../../plugins/ppapi/mock_platform_image_2d.h',
'../../plugins/ppapi/mock_plugin_delegate.cc', '../../plugins/ppapi/mock_plugin_delegate.cc',
'../../plugins/ppapi/mock_plugin_delegate.h', '../../plugins/ppapi/mock_plugin_delegate.h',
'../../plugins/ppapi/mock_resource.h', '../../plugins/ppapi/mock_resource.h',
......
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