diff options
author | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-03 05:45:55 +0000 |
---|---|---|
committer | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-03 05:45:55 +0000 |
commit | 503b1574e293e27e90b8d009ea1cec56961e7907 (patch) | |
tree | 9b29fcc9cb049c125ee2f9472accc6381042d18b | |
parent | be9827184d20dea9dd7b7bfaa6e727e34af59d9d (diff) | |
download | chromium_src-503b1574e293e27e90b8d009ea1cec56961e7907.zip chromium_src-503b1574e293e27e90b8d009ea1cec56961e7907.tar.gz chromium_src-503b1574e293e27e90b8d009ea1cec56961e7907.tar.bz2 |
Revert 40490 - Make the pepper 2D flush callback actually function as advertised. It will now
get called asynchronously when the bits are actually copied to the screen,
rather than synchronously from inside the paint function. This makes it useful
for plugins to use the callback for rate limiting.
This also adds a lot of infrastructure for running tests on pepper devices, and
includes a unit test for the new flush behavior.
I made the existing RenderProcess object an abstract interface and made the
existing MockProcess (renamed to be more clear) implement that. This avoids
a static cast that would actually crash during a unit test because some code
was hardcoded to expect a RenderProcess object.
This fixes base's IDMap iterator which has apparently never been used for an
IDMap with ownership semantics.
TEST=Unit test included
BUG=none
Review URL: http://codereview.chromium.org/661124
TBR=brettw@chromium.org
Review URL: http://codereview.chromium.org/660439
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@40494 0039d316-1c4b-4281-b951-d872f2087c98
29 files changed, 456 insertions, 634 deletions
diff --git a/base/id_map.h b/base/id_map.h index 00ef16a..acfba42 100644 --- a/base/id_map.h +++ b/base/id_map.h @@ -101,7 +101,7 @@ class IDMap { template<class ReturnType> class Iterator { public: - Iterator(IDMap<T, OS>* map) + Iterator(IDMap<T>* map) : map_(map), iter_(map_->data_.begin()) { ++map_->iteration_depth_; @@ -139,7 +139,7 @@ class IDMap { } } - IDMap<T, OS>* map_; + IDMap<T>* map_; typename HashTable::const_iterator iter_; }; diff --git a/chrome/browser/renderer_host/browser_render_process_host.cc b/chrome/browser/renderer_host/browser_render_process_host.cc index 55dcc52..5230bab 100644 --- a/chrome/browser/renderer_host/browser_render_process_host.cc +++ b/chrome/browser/renderer_host/browser_render_process_host.cc @@ -51,7 +51,7 @@ #include "chrome/common/process_watcher.h" #include "chrome/common/render_messages.h" #include "chrome/common/result_codes.h" -#include "chrome/renderer/render_process_impl.h" +#include "chrome/renderer/render_process.h" #include "chrome/renderer/render_thread.h" #include "grit/generated_resources.h" #include "ipc/ipc_logging.h" @@ -89,7 +89,7 @@ class RendererMainThread : public base::Thread { CoInitialize(NULL); #endif - render_process_ = new RenderProcessImpl(); + render_process_ = new RenderProcess(); render_process_->set_main_thread(new RenderThread(channel_id_)); // It's a little lame to manually set this flag. But the single process // RendererThread will receive the WM_QUIT. We don't need to assert on diff --git a/chrome/chrome_renderer.gypi b/chrome/chrome_renderer.gypi index ec3201b..7acf628 100755 --- a/chrome/chrome_renderer.gypi +++ b/chrome/chrome_renderer.gypi @@ -109,9 +109,8 @@ 'renderer/print_web_view_helper_linux.cc', 'renderer/print_web_view_helper_mac.mm', 'renderer/print_web_view_helper_win.cc', + 'renderer/render_process.cc', 'renderer/render_process.h', - 'renderer/render_process_impl.cc', - 'renderer/render_process_impl.h', 'renderer/render_thread.cc', 'renderer/render_thread.h', 'renderer/render_view.cc', diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index 2171cc5..533d779 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -85,7 +85,6 @@ 'renderer/mock_keyboard_driver_win.h', 'renderer/mock_printer.cc', 'renderer/mock_printer.h', - 'renderer/mock_render_process.cc', 'renderer/mock_render_process.h', 'renderer/mock_render_thread.cc', 'renderer/mock_render_thread.h', @@ -899,7 +898,6 @@ 'renderer/net/render_dns_master_unittest.cc', 'renderer/net/render_dns_queue_unittest.cc', 'renderer/paint_aggregator_unittest.cc', - 'renderer/pepper_devices_unittest.cc', 'renderer/render_process_unittest.cc', 'renderer/render_thread_unittest.cc', 'renderer/render_view_unittest.cc', diff --git a/chrome/common/transport_dib.h b/chrome/common/transport_dib.h index 4f8051e..e36e8bf 100644 --- a/chrome/common/transport_dib.h +++ b/chrome/common/transport_dib.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2006-2009 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. @@ -90,15 +90,10 @@ class TransportDIB { static Handle DefaultHandleValue() { return -1; } #endif - // Create a new TransportDIB, returning NULL on failure. - // - // The size is the minimum size in bytes of the memory backing the transport - // DIB (we may actually allocate more than that to give us better reuse when - // cached). - // - // The sequence number is used to uniquely identify the transport DIB. It - // should be unique for all transport DIBs ever created in the same - // renderer. + // Create a new TransportDIB + // size: the minimum size, in bytes + // epoch: Windows only: a global counter. See comment above. + // returns: NULL on failure static TransportDIB* Create(size_t size, uint32 sequence_num); // Map the referenced transport DIB. Returns NULL on failure. diff --git a/chrome/renderer/mock_render_process.cc b/chrome/renderer/mock_render_process.cc deleted file mode 100644 index a71fcab..0000000 --- a/chrome/renderer/mock_render_process.cc +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (c) 2010 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 "chrome/renderer/mock_render_process.h" - -#include "base/gfx/rect.h" -#include "chrome/common/transport_dib.h" - -MockRenderProcess::MockRenderProcess() - : transport_dib_next_sequence_number_(0) { -} - -MockRenderProcess::~MockRenderProcess() { -} - -skia::PlatformCanvas* MockRenderProcess::GetDrawingCanvas( - TransportDIB** memory, - const gfx::Rect& rect) { - size_t stride = skia::PlatformCanvas::StrideForWidth(rect.width()); - size_t size = stride * rect.height(); - - // Unlike RenderProcessImpl, when we're a test, we can just create transport - // DIBs in the current process, since there is no sandbox protecting us (and - // no browser process to ask for one in any case). - *memory = TransportDIB::Create(size, transport_dib_next_sequence_number_++); - if (!*memory) - return NULL; - return (*memory)->GetPlatformCanvas(rect.width(), rect.height()); -} - -void MockRenderProcess::ReleaseTransportDIB(TransportDIB* memory) { - delete memory; -} - -bool MockRenderProcess::UseInProcessPlugins() const { - return true; -} - -bool MockRenderProcess::HasInitializedMediaLibrary() const { - return false; -} - - diff --git a/chrome/renderer/mock_render_process.h b/chrome/renderer/mock_render_process.h index fd286a1..49bc02c 100644 --- a/chrome/renderer/mock_render_process.h +++ b/chrome/renderer/mock_render_process.h @@ -1,30 +1,20 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2008 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 CHROME_RENDERER_MOCK_RENDER_PROCESS_H_ #define CHROME_RENDERER_MOCK_RENDER_PROCESS_H_ -#include "chrome/renderer/render_process.h" +#include "chrome/common/child_process.h" -// This class is a mock of the child process singleton which we use during -// running of the RenderView unit tests. -class MockRenderProcess : public RenderProcess { - public: - MockRenderProcess(); - virtual ~MockRenderProcess(); - - // RenderProcess implementation. - virtual skia::PlatformCanvas* GetDrawingCanvas(TransportDIB** memory, - const gfx::Rect& rect); - virtual void ReleaseTransportDIB(TransportDIB* memory); - virtual bool UseInProcessPlugins() const; - virtual bool HasInitializedMediaLibrary() const; +class ChildThread; - private: - uint32 transport_dib_next_sequence_number_; - - DISALLOW_COPY_AND_ASSIGN(MockRenderProcess); +// This class is a trivial mock of the child process singleton. It is necessary +// so we don't trip DCHECKs in ChildProcess::ReleaseProcess() when destroying +// a render widget instance. +class MockProcess : public ChildProcess { + public: + explicit MockProcess() : ChildProcess() {} }; #endif // CHROME_RENDERER_MOCK_RENDER_PROCESS_H_ diff --git a/chrome/renderer/pepper_devices.cc b/chrome/renderer/pepper_devices.cc index c47b846..cfd8076 100644 --- a/chrome/renderer/pepper_devices.cc +++ b/chrome/renderer/pepper_devices.cc @@ -3,27 +3,17 @@ // found in the LICENSE file. #include "chrome/renderer/pepper_devices.h" -#include "chrome/renderer/webplugin_delegate_pepper.h" #include "skia/ext/platform_canvas.h" -#include "webkit/glue/plugins/plugin_instance.h" -#include "webkit/glue/webplugin.h" namespace { - -const uint32 kBytesPerPixel = 4; // Only 8888 RGBA for now. - + const uint32 kBytesPerPixel = 4; // Only 8888 RGBA for now. } // namespace int Graphics2DDeviceContext::next_buffer_id_ = 0; -Graphics2DDeviceContext::Graphics2DDeviceContext( - WebPluginDelegatePepper* plugin_delegate) - : plugin_delegate_(plugin_delegate) { -} - NPError Graphics2DDeviceContext::Initialize( - gfx::Rect window_rect, const NPDeviceContext2DConfig* config, - NPDeviceContext2D* context) { + gfx::Rect window_rect, const NPDeviceContext2DConfig* config, + NPDeviceContext2D* context) { int width = window_rect.width(); int height = window_rect.height(); uint32 buffer_size = width * height * kBytesPerPixel; @@ -85,47 +75,22 @@ NPError Graphics2DDeviceContext::Flush(SkBitmap* committed_bitmap, paint.setXfermodeMode(SkXfermode::kSrc_Mode); committed_canvas.drawBitmapRect( canvas_->getTopPlatformDevice().accessBitmap(false), - &src_rect, dest_rect, &paint); + &src_rect, dest_rect); committed_bitmap->setIsOpaque(false); - // Cause the updated part of the screen to be repainted. This will happen - // asynchronously. - // TODO(brettw) is this the coorect coordinate system? - gfx::Rect dest_gfx_rect(context->dirty.left, context->dirty.top, - context->dirty.right - context->dirty.left, - context->dirty.bottom - context->dirty.top); - - plugin_delegate_->instance()->webplugin()->InvalidateRect(dest_gfx_rect); - - // Save the callback to execute later. See |unpainted_flush_callbacks_| in - // the header file. - if (callback) { - unpainted_flush_callbacks_.push_back( - FlushCallbackData(callback, id, context, user_data)); - } + // Invoke the callback to inform the caller the work was done. + // TODO(brettw) this is not how we want this to work, this should + // happen when the frame is painted so the plugin knows when it can draw + // the next frame. + // + // This should also be called in the failure cases as well. + if (callback != NULL) + (*callback)(id, context, NPERR_NO_ERROR, user_data); return NPERR_NO_ERROR; } -void Graphics2DDeviceContext::RenderViewInitiatedPaint() { - // Move all "unpainted" callbacks to the painted state. See - // |unpainted_flush_callbacks_| in the header for more. - std::copy(unpainted_flush_callbacks_.begin(), - unpainted_flush_callbacks_.end(), - std::back_inserter(painted_flush_callbacks_)); - unpainted_flush_callbacks_.clear(); -} - -void Graphics2DDeviceContext::RenderViewFlushedPaint() { - // Notify all "painted" callbacks. See |unpainted_flush_callbacks_| in the - // header for more. - for (size_t i = 0; i < painted_flush_callbacks_.size(); i++) { - const FlushCallbackData& data = painted_flush_callbacks_[i]; - data.function(data.npp, data.context, NPERR_NO_ERROR, data.user_data); - } - painted_flush_callbacks_.clear(); -} AudioDeviceContext::~AudioDeviceContext() { if (stream_id_) { diff --git a/chrome/renderer/pepper_devices.h b/chrome/renderer/pepper_devices.h index f608735..24fa506 100644 --- a/chrome/renderer/pepper_devices.h +++ b/chrome/renderer/pepper_devices.h @@ -6,7 +6,6 @@ #define CHROME_RENDERER_PEPPER_DEVICES_H_ #include "base/basictypes.h" -#include "base/gfx/rect.h" #include "base/scoped_ptr.h" #include "base/shared_memory.h" #include "base/simple_thread.h" @@ -18,16 +17,12 @@ #include "third_party/npapi/bindings/npapi_extensions.h" #include "third_party/skia/include/core/SkBitmap.h" -class WebPluginDelegatePepper; - // Lists all contexts currently open for painting. These are ones requested by // the plugin but not destroyed by it yet. The source pointer is the raw // pixels. We use this to look up the corresponding transport DIB when the // plugin tells us to flush or destroy it. class Graphics2DDeviceContext { public: - explicit Graphics2DDeviceContext(WebPluginDelegatePepper* plugin_delegate); - NPError Initialize(gfx::Rect window_rect, const NPDeviceContext2DConfig* config, NPDeviceContext2D* context); @@ -36,57 +31,15 @@ class Graphics2DDeviceContext { NPDeviceFlushContextCallbackPtr callback, NPP id, void* user_data); - // Notifications that the render view has rendered the page and that it has - // been flushed to the screen. - void RenderViewInitiatedPaint(); - void RenderViewFlushedPaint(); - TransportDIB* transport_dib() { return transport_dib_.get(); } private: - struct FlushCallbackData { - FlushCallbackData(NPDeviceFlushContextCallbackPtr f, - NPP n, - NPDeviceContext2D* c, - NPUserData* u) - : function(f), - npp(n), - context(c), - user_data(u) { - } - - NPDeviceFlushContextCallbackPtr function; - NPP npp; - NPDeviceContext2D* context; - NPUserData* user_data; - }; - typedef std::vector<FlushCallbackData> FlushCallbackVector; - - WebPluginDelegatePepper* plugin_delegate_; - static int32 next_buffer_id_; scoped_ptr<TransportDIB> transport_dib_; // The canvas associated with the transport DIB, containing the mapped // memory of the image. scoped_ptr<skia::PlatformCanvas> canvas_; - - // The plugin may be constantly giving us paint messages. "Unpainted" ones - // are paint requests which have never been painted. These could have been - // done while the RenderView was already waiting for an ACK from a previous - // paint, so won't generate a new one yet. - // - // "Painted" ones are those paints that have been painted by RenderView, but - // for which the ACK from the browser has not yet been received. - // - // When we get updates from a plugin with a callback, it is first added to - // the unpainted callbacks. When the renderer has initiated a paint, we'll - // move it to the painted callbacks list. When the renderer receives a flush, - // we'll execute the callback and remove it from the list. - FlushCallbackVector unpainted_flush_callbacks_; - FlushCallbackVector painted_flush_callbacks_; - - DISALLOW_COPY_AND_ASSIGN(Graphics2DDeviceContext); }; diff --git a/chrome/renderer/pepper_devices_unittest.cc b/chrome/renderer/pepper_devices_unittest.cc deleted file mode 100644 index 89a371f..0000000 --- a/chrome/renderer/pepper_devices_unittest.cc +++ /dev/null @@ -1,248 +0,0 @@ -// Copyright (c) 2010 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 <map> -#include <vector> - -#include "base/string_util.h" -#include "build/build_config.h" -#include "chrome/common/render_messages.h" -#include "chrome/renderer/pepper_devices.h" -#include "chrome/renderer/webplugin_delegate_pepper.h" -#include "chrome/test/render_view_test.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "third_party/npapi/bindings/npapi.h" -#include "third_party/npapi/bindings/npruntime.h" -#include "third_party/WebKit/WebKit/chromium/public/WebPlugin.h" -#include "third_party/WebKit/WebKit/chromium/public/WebPluginParams.h" -#include "third_party/WebKit/WebKit/chromium/public/WebRect.h" -#include "webkit/glue/plugins/plugin_instance.h" -#include "webkit/glue/plugins/plugin_list.h" -#include "webkit/glue/webplugin_impl.h" - -class PepperDeviceTest; - -namespace { - -const char kTestPluginMimeType[] = "chrome-test/pepper-device-test"; - -// This maps the NPP instances to the test object so our C callbacks can easily -// get back to the object. There will normally be only one item in this map. -static std::map<NPP, PepperDeviceTest*> active_tests; - -NPError NPP_New(NPMIMEType plugin_type, NPP instance, - uint16 mode, int16 argc, char* argn[], - char* argv[], NPSavedData* saved) { - // Watch out: active_tests won't contain the NPP pointer until after this - // call is complete, so don't use it. - return NPERR_NO_ERROR; -} - -NPError NPP_Destroy(NPP instance, NPSavedData** saved) { - if (!instance) - return NPERR_INVALID_INSTANCE_ERROR; - return NPERR_NO_ERROR; -} - -NPError NPP_SetWindow(NPP instance, NPWindow* window) { - return NPERR_NO_ERROR; -} - -int16 NPP_HandleEvent(NPP instance, void* event) { - return 0; -} - -NPError NPP_GetValue(NPP instance, NPPVariable variable, void* value) { - if (!instance) - return NPERR_INVALID_INSTANCE_ERROR; - switch (variable) { - case NPPVpluginNeedsXEmbed: - *static_cast<NPBool*>(value) = 1; - return NPERR_NO_ERROR; - default: - return NPERR_INVALID_PARAM; - } -} - -NPError NPP_SetValue(NPP instance, NPNVariable variable, void* value) { - return NPERR_NO_ERROR; -} - -NPError API_CALL NP_GetEntryPoints(NPPluginFuncs* plugin_funcs) { - plugin_funcs->newp = NPP_New; - plugin_funcs->destroy = NPP_Destroy; - plugin_funcs->setwindow = NPP_SetWindow; - plugin_funcs->event = NPP_HandleEvent; - plugin_funcs->getvalue = NPP_GetValue; - plugin_funcs->setvalue = NPP_SetValue; - return NPERR_NO_ERROR; -} - -#if defined(OS_MACOSX) -NPError API_CALL NP_Initialize(NPNetscapeFuncs* browser_funcs) { - return NPERR_NO_ERROR; -} -#else -NPError API_CALL NP_Initialize(NPNetscapeFuncs* browser_funcs, - NPPluginFuncs* plugin_funcs) { - NP_GetEntryPoints(plugin_funcs); - return NPERR_NO_ERROR; -} -#endif - -NPError API_CALL NP_Shutdown() { - return NPERR_NO_ERROR; -} - -} // namespace - -// PepperDeviceTest ------------------------------------------------------------ - -class PepperDeviceTest : public RenderViewTest { - public: - PepperDeviceTest(); - ~PepperDeviceTest(); - - const FilePath& plugin_path() const { return version_info_.path; } - - WebPluginDelegatePepper* pepper_plugin() const { return pepper_plugin_; } - - NPP npp() const { return pepper_plugin_->instance()->npp(); } - - protected: - // Logs that the given flush command was called in flush_calls. - static void API_CALL FlushCalled(NPP instance, - NPDeviceContext* context, - NPError err, - NPUserData* user_data); - - // A log of flush commands we can use to check the async callbacks. - struct FlushData { - NPP instance; - NPDeviceContext* context; - NPError err; - NPUserData* user_data; - }; - std::vector<FlushData> flush_calls_; - - private: - // testing::Test implementation. - virtual void SetUp(); - virtual void TearDown(); - - NPAPI::PluginVersionInfo version_info_; - - scoped_ptr<webkit_glue::WebPluginImpl> plugin_; - WebPluginDelegatePepper* pepper_plugin_; // FIXME(brettw): check lifetime. -}; - -PepperDeviceTest::PepperDeviceTest() { - version_info_.path = FilePath(FILE_PATH_LITERAL("pepper-device-tester")); - version_info_.product_name = ASCIIToWide("Pepper device test plugin"); - version_info_.file_description = ASCIIToWide("Pepper device test plugin"); - version_info_.file_version = ASCIIToWide("1"); - version_info_.mime_types = ASCIIToWide(kTestPluginMimeType); - NPAPI::PluginEntryPoints entry_points = { -#if !defined(OS_POSIX) || defined(OS_MACOSX) - NP_GetEntryPoints, -#endif - NP_Initialize, - NP_Shutdown - }; - version_info_.entry_points = entry_points; -} - -PepperDeviceTest::~PepperDeviceTest() { -} - -void PepperDeviceTest::SetUp() { - RenderViewTest::SetUp(); - - NPAPI::PluginList::Singleton()->RegisterInternalPlugin(version_info_); - - // Create the WebKit plugin with no delegates (this seems to work - // sufficiently for the test). - WebKit::WebPluginParams params; - plugin_.reset(new webkit_glue::WebPluginImpl( - NULL, params, base::WeakPtr<webkit_glue::WebPluginPageDelegate>())); - - // Create a pepper plugin for the RenderView. - pepper_plugin_ = WebPluginDelegatePepper::Create( - plugin_path(), kTestPluginMimeType, view_->AsWeakPtr()); - ASSERT_TRUE(pepper_plugin_); - ASSERT_TRUE(pepper_plugin_->Initialize(GURL(), std::vector<std::string>(), - std::vector<std::string>(), - plugin_.get(), false)); - - // Normally the RenderView creates the pepper plugin and registers it with - // its internal list. Since we're creating it manually, we have to reach in - // and register it to prevent tear-down from asserting. - view_->current_pepper_plugins_.insert(pepper_plugin_); - - active_tests[npp()] = this; - - // Need to specify a window size or graphics calls will fail on the 0x0 - // bitmap. - gfx::Rect rect(0, 0, 100, 100); - view_->OnResize(rect.size(), gfx::Rect()); - pepper_plugin_->UpdateGeometry(rect, rect); -} - -void PepperDeviceTest::TearDown() { - active_tests.erase(active_tests.find(npp())); - - plugin_.reset(); - if (pepper_plugin_) - pepper_plugin_->PluginDestroyed(); - - NPAPI::PluginList::Singleton()->UnregisterInternalPlugin(version_info_.path); - - RenderViewTest::TearDown(); -} - -// static -void API_CALL PepperDeviceTest::FlushCalled(NPP instance, - NPDeviceContext* context, - NPError err, - NPUserData* user_data) { - if (active_tests.find(instance) == active_tests.end()) - return; - PepperDeviceTest* that = active_tests[instance]; - - FlushData flush_data; - flush_data.instance = instance; - flush_data.context = context; - flush_data.err = err; - flush_data.user_data = user_data; - that->flush_calls_.push_back(flush_data); -} - -// ----------------------------------------------------------------------------- - -TEST_F(PepperDeviceTest, Flush) { - // Create a 2D device. - NPDeviceContext2DConfig config; - NPDeviceContext2D context; - EXPECT_EQ(NPERR_NO_ERROR, - pepper_plugin()->Device2DInitializeContext(&config, &context)); - - // Flush the bitmap. Here we fake the invalidate call to the RenderView since - // there isn't an actual visible web page that would otherwise get painted. - // The callback should not get called synchronously. - pepper_plugin()->Device2DFlushContext(npp(), &context, &FlushCalled, NULL); - view_->didInvalidateRect(WebKit::WebRect(0, 0, 100, 100)); - EXPECT_TRUE(flush_calls_.empty()); - - // Run the message loop which should process the pending paints, there should - // still be no callbacks since the stuff hasn't been copied to the screen, - // but there should be a paint message sent to the browser. - MessageLoop::current()->RunAllPending(); - EXPECT_TRUE(flush_calls_.empty()); - EXPECT_TRUE(render_thread_.sink().GetFirstMessageMatching( - ViewHostMsg_UpdateRect::ID)); - - // Send a paint ACK, this should trigger the callback. - view_->OnMessageReceived(ViewMsg_UpdateRect_ACK(view_->routing_id())); - EXPECT_EQ(1u, flush_calls_.size()); -} diff --git a/chrome/renderer/render_process.cc b/chrome/renderer/render_process.cc new file mode 100644 index 0000000..f5d72c8 --- /dev/null +++ b/chrome/renderer/render_process.cc @@ -0,0 +1,298 @@ +// Copyright (c) 2010 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 "build/build_config.h" + +#if defined(OS_WIN) +#include <windows.h> +#include <objidl.h> +#include <mlang.h> +#endif + +#include "chrome/renderer/render_process.h" + +#include "base/basictypes.h" +#include "base/command_line.h" +#include "base/compiler_specific.h" +#include "base/file_util.h" +#include "base/message_loop.h" +#include "base/histogram.h" +#include "base/path_service.h" +#include "base/sys_info.h" +// TODO(jar): DNS calls should be renderer specific, not including browser. +#include "chrome/browser/net/dns_global.h" +#include "chrome/common/chrome_switches.h" +#include "chrome/common/chrome_paths.h" +#include "chrome/common/render_messages.h" +#include "chrome/common/nacl_types.h" +#include "chrome/common/transport_dib.h" +#include "chrome/renderer/render_view.h" +#include "ipc/ipc_channel.h" +#include "ipc/ipc_message_utils.h" +#include "media/base/media.h" +#include "media/base/media_switches.h" +#include "native_client/src/trusted/plugin/nacl_entry_points.h" +#include "webkit/glue/webkit_glue.h" + +#if defined(OS_MACOSX) +#include "base/mac_util.h" +#endif + +//----------------------------------------------------------------------------- + +RenderProcess::RenderProcess() + : ALLOW_THIS_IN_INITIALIZER_LIST(shared_mem_cache_cleaner_( + base::TimeDelta::FromSeconds(5), + this, &RenderProcess::ClearTransportDIBCache)), + sequence_number_(0) { + in_process_plugins_ = InProcessPlugins(); + for (size_t i = 0; i < arraysize(shared_mem_cache_); ++i) + shared_mem_cache_[i] = NULL; + +#if defined(OS_WIN) + // HACK: See http://b/issue?id=1024307 for rationale. + if (GetModuleHandle(L"LPK.DLL") == NULL) { + // Makes sure lpk.dll is loaded by gdi32 to make sure ExtTextOut() works + // when buffering into a EMF buffer for printing. + typedef BOOL (__stdcall *GdiInitializeLanguagePack)(int LoadedShapingDLLs); + GdiInitializeLanguagePack gdi_init_lpk = + reinterpret_cast<GdiInitializeLanguagePack>(GetProcAddress( + GetModuleHandle(L"GDI32.DLL"), + "GdiInitializeLanguagePack")); + DCHECK(gdi_init_lpk); + if (gdi_init_lpk) { + gdi_init_lpk(0); + } + } +#endif + + // Out of process dev tools rely upon auto break behavior. + webkit_glue::SetJavaScriptFlags( + L"--debugger-auto-break" + // Enable lazy in-memory profiling. + L" --prof --prof-lazy --logfile=* --compress-log"); + + const CommandLine& command_line = *CommandLine::ForCurrentProcess(); + if (command_line.HasSwitch(switches::kJavaScriptFlags)) { + webkit_glue::SetJavaScriptFlags( + command_line.GetSwitchValue(switches::kJavaScriptFlags)); + } + + if (command_line.HasSwitch(switches::kEnableWatchdog)) { + // TODO(JAR): Need to implement renderer IO msgloop watchdog. + } + + if (command_line.HasSwitch(switches::kDumpHistogramsOnExit)) { + StatisticsRecorder::set_dump_on_exit(true); + } + +#ifndef DISABLE_NACL + if (command_line.HasSwitch(switches::kInternalNaCl)) + RegisterInternalNaClPlugin(RenderProcess::LaunchNaClProcess); +#endif + + if (!command_line.HasSwitch(switches::kDisableByteRangeSupport)) { + webkit_glue::SetMediaCacheEnabled(true); + } + +#if defined(OS_MACOSX) + FilePath bundle_path = mac_util::MainAppBundlePath(); + + initialized_media_library_ = + media::InitializeMediaLibrary(bundle_path.Append("Libraries")); +#else + FilePath module_path; + initialized_media_library_ = + PathService::Get(base::DIR_MODULE, &module_path) && + media::InitializeMediaLibrary(module_path); + + // TODO(hclam): Add more checks here. Currently this is not used. + if (CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableOpenMax)) { + media::InitializeOpenMaxLibrary(module_path); + } +#endif +} + +RenderProcess::~RenderProcess() { + // TODO(port): Try and limit what we pull in for our non-Win unit test bundle. +#ifndef NDEBUG + // log important leaked objects + webkit_glue::CheckForLeaks(); +#endif + + GetShutDownEvent()->Signal(); + ClearTransportDIBCache(); +} + +bool RenderProcess::InProcessPlugins() { + const CommandLine& command_line = *CommandLine::ForCurrentProcess(); +#if defined(OS_LINUX) + // Plugin processes require a UI message loop, and the Linux message loop + // implementation only allows one UI loop per process. + if (command_line.HasSwitch(switches::kInProcessPlugins)) + NOTIMPLEMENTED() << ": in process plugins not supported on Linux"; + return command_line.HasSwitch(switches::kInProcessPlugins); +#else + return command_line.HasSwitch(switches::kInProcessPlugins) || + command_line.HasSwitch(switches::kSingleProcess); +#endif +} + +bool RenderProcess::LaunchNaClProcess(const char* url, + int imc_fd, + nacl::Handle* imc_handle, + nacl::Handle* nacl_process_handle, + int* nacl_process_id) { + // TODO(gregoryd): nacl::FileDescriptor will be soon merged with + // base::FileDescriptor + nacl::FileDescriptor imc_descriptor; + base::ProcessHandle nacl_process; + if (!RenderThread::current()->Send( + new ViewHostMsg_LaunchNaCl(ASCIIToWide(url), + imc_fd, + &imc_descriptor, + &nacl_process, + reinterpret_cast<base::ProcessId*>(nacl_process_id)))) { + return false; + } + *imc_handle = nacl::ToNativeHandle(imc_descriptor); + *nacl_process_handle = nacl_process; + return true; +} + +// ----------------------------------------------------------------------------- +// Platform specific code for dealing with bitmap transport... + +TransportDIB* RenderProcess::CreateTransportDIB(size_t size) { +#if defined(OS_WIN) || defined(OS_LINUX) + // Windows and Linux create transport DIBs inside the renderer + return TransportDIB::Create(size, sequence_number_++); +#elif defined(OS_MACOSX) // defined(OS_WIN) || defined(OS_LINUX) + // Mac creates transport DIBs in the browser, so we need to do a sync IPC to + // get one. + TransportDIB::Handle handle; + IPC::Message* msg = new ViewHostMsg_AllocTransportDIB(size, &handle); + if (!main_thread()->Send(msg)) + return NULL; + if (handle.fd < 0) + return NULL; + return TransportDIB::Map(handle); +#endif // defined(OS_MACOSX) +} + +void RenderProcess::FreeTransportDIB(TransportDIB* dib) { + if (!dib) + return; + +#if defined(OS_MACOSX) + // On Mac we need to tell the browser that it can drop a reference to the + // shared memory. + IPC::Message* msg = new ViewHostMsg_FreeTransportDIB(dib->id()); + main_thread()->Send(msg); +#endif + + delete dib; +} + +// ----------------------------------------------------------------------------- + + +skia::PlatformCanvas* RenderProcess::GetDrawingCanvas( + TransportDIB** memory, const gfx::Rect& rect) { + int width = rect.width(); + int height = rect.height(); + const size_t stride = skia::PlatformCanvas::StrideForWidth(rect.width()); +#if defined(OS_LINUX) + const size_t max_size = base::SysInfo::MaxSharedMemorySize(); +#else + const size_t max_size = 0; +#endif + + // If the requested size is too big, reduce the height. Ideally we might like + // to reduce the width as well to make the size reduction more "balanced", but + // it rarely comes up in practice. + if ((max_size != 0) && (height * stride > max_size)) + height = max_size / stride; + + const size_t size = height * stride; + + if (!GetTransportDIBFromCache(memory, size)) { + *memory = CreateTransportDIB(size); + if (!*memory) + return false; + } + + return (*memory)->GetPlatformCanvas(width, height); +} + +void RenderProcess::ReleaseTransportDIB(TransportDIB* mem) { + if (PutSharedMemInCache(mem)) { + shared_mem_cache_cleaner_.Reset(); + return; + } + + FreeTransportDIB(mem); +} + +bool RenderProcess::GetTransportDIBFromCache(TransportDIB** mem, + size_t size) { + // look for a cached object that is suitable for the requested size. + for (size_t i = 0; i < arraysize(shared_mem_cache_); ++i) { + if (shared_mem_cache_[i] && + size <= shared_mem_cache_[i]->size()) { + *mem = shared_mem_cache_[i]; + shared_mem_cache_[i] = NULL; + return true; + } + } + + return false; +} + +int RenderProcess::FindFreeCacheSlot(size_t size) { + // simple algorithm: + // - look for an empty slot to store mem, or + // - if full, then replace smallest entry which is smaller than |size| + for (size_t i = 0; i < arraysize(shared_mem_cache_); ++i) { + if (shared_mem_cache_[i] == NULL) + return i; + } + + size_t smallest_size = size; + int smallest_index = -1; + + for (size_t i = 1; i < arraysize(shared_mem_cache_); ++i) { + const size_t entry_size = shared_mem_cache_[i]->size(); + if (entry_size < smallest_size) { + smallest_size = entry_size; + smallest_index = i; + } + } + + if (smallest_index != -1) { + FreeTransportDIB(shared_mem_cache_[smallest_index]); + shared_mem_cache_[smallest_index] = NULL; + } + + return smallest_index; +} + +bool RenderProcess::PutSharedMemInCache(TransportDIB* mem) { + const int slot = FindFreeCacheSlot(mem->size()); + if (slot == -1) + return false; + + shared_mem_cache_[slot] = mem; + return true; +} + +void RenderProcess::ClearTransportDIBCache() { + for (size_t i = 0; i < arraysize(shared_mem_cache_); ++i) { + if (shared_mem_cache_[i]) { + FreeTransportDIB(shared_mem_cache_[i]); + shared_mem_cache_[i] = NULL; + } + } +} diff --git a/chrome/renderer/render_process.h b/chrome/renderer/render_process.h index c4c7ca3..4c682dc 100644 --- a/chrome/renderer/render_process.h +++ b/chrome/renderer/render_process.h @@ -1,34 +1,29 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2006-2008 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 CHROME_RENDERER_RENDER_PROCESS_H_ -#define CHROME_RENDERER_RENDER_PROCESS_H_ +#ifndef CHROME_RENDERER_RENDER_PROCESS_H__ +#define CHROME_RENDERER_RENDER_PROCESS_H__ +#include "base/timer.h" #include "chrome/common/child_process.h" +#include "chrome/renderer/render_thread.h" +#include "native_client/src/shared/imc/nacl_imc.h" #include "skia/ext/platform_canvas.h" -class TransportDIB; - namespace gfx { class Rect; } -namespace skia { -class PlatformCanvas; -} +class TransportDIB; -// A abstract interface representing the renderer end of the browser<->renderer -// connection. The opposite end is the RenderProcessHost. This is a singleton -// object for each renderer. -// -// RenderProcessImpl implements this interface for the regular browser. -// MockRenderProcess implements this interface for certain tests, especially -// ones derived from RenderViewTest. +// Represents the renderer end of the browser<->renderer connection. The +// opposite end is the RenderProcessHost. This is a singleton object for +// each renderer. class RenderProcess : public ChildProcess { public: - RenderProcess() {} - virtual ~RenderProcess() {} + RenderProcess(); + ~RenderProcess(); // Get a canvas suitable for drawing and transporting to the browser // memory: (output) the transport DIB memory @@ -37,31 +32,72 @@ class RenderProcess : public ChildProcess { // // When no longer needed, you should pass the TransportDIB to // ReleaseTransportDIB so that it can be recycled. - virtual skia::PlatformCanvas* GetDrawingCanvas(TransportDIB** memory, - const gfx::Rect& rect) = 0; + skia::PlatformCanvas* GetDrawingCanvas( + TransportDIB** memory, const gfx::Rect& rect); // Frees shared memory allocated by AllocSharedMemory. You should only use // this function to free the SharedMemory object. - virtual void ReleaseTransportDIB(TransportDIB* memory) = 0; + void ReleaseTransportDIB(TransportDIB* memory); // Returns true if plugins should be loaded in-process. - virtual bool UseInProcessPlugins() const = 0; + bool in_process_plugins() const { return in_process_plugins_; } - virtual bool HasInitializedMediaLibrary() const = 0; + bool initialized_media_library() const { return initialized_media_library_; } - // Returns a pointer to the RenderProcess singleton instance. Assuming that - // we're actually a renderer or a renderer test, this static cast will - // be correct. + // Returns a pointer to the RenderProcess singleton instance. static RenderProcess* current() { return static_cast<RenderProcess*>(ChildProcess::current()); } - // Just like UseInProcessPlugins(), but called before RenderProcess is - // created. + // Just like in_process_plugins(), but called before RenderProcess is created. static bool InProcessPlugins(); + // Sends a message to the browser process asking to launch a new NaCl process. + // Called from NaCl plugin code. + static bool LaunchNaClProcess(const char* url, + int imc_fd, + nacl::Handle* imc_handle, + nacl::Handle* nacl_process_handle, + int* nacl_process_id); + private: + // Look in the shared memory cache for a suitable object to reuse. + // result: (output) the memory found + // size: the resulting memory will be >= this size, in bytes + // returns: false if a suitable DIB memory could not be found + bool GetTransportDIBFromCache(TransportDIB** result, size_t size); + + // Maybe put the given shared memory into the shared memory cache. Returns + // true if the SharedMemory object was stored in the cache; otherwise, false + // is returned. + bool PutSharedMemInCache(TransportDIB* memory); + + void ClearTransportDIBCache(); + + // Return the index of a free cache slot in which to install a transport DIB + // of the given size. If all entries in the cache are larger than the given + // size, this doesn't free any slots and returns -1. + int FindFreeCacheSlot(size_t size); + + // Create a new transport DIB of, at least, the given size. Return NULL on + // error. + TransportDIB* CreateTransportDIB(size_t size); + void FreeTransportDIB(TransportDIB*); + + // A very simplistic and small cache. If an entry in this array is non-null, + // then it points to a SharedMemory object that is available for reuse. + TransportDIB* shared_mem_cache_[2]; + + // This DelayTimer cleans up our cache 5 seconds after the last use. + base::DelayTimer<RenderProcess> shared_mem_cache_cleaner_; + + // TransportDIB sequence number + uint32 sequence_number_; + + bool in_process_plugins_; + bool initialized_media_library_; + DISALLOW_COPY_AND_ASSIGN(RenderProcess); }; -#endif // CHROME_RENDERER_RENDER_PROCESS_H_ +#endif // CHROME_RENDERER_RENDER_PROCESS_H__ diff --git a/chrome/renderer/render_process_unittest.cc b/chrome/renderer/render_process_unittest.cc index f52d694..5692d81 100644 --- a/chrome/renderer/render_process_unittest.cc +++ b/chrome/renderer/render_process_unittest.cc @@ -1,11 +1,11 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2009 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 "base/gfx/rect.h" #include "base/sys_info.h" #include "base/string_util.h" -#include "chrome/renderer/render_process_impl.h" +#include "chrome/renderer/render_process.h" #include "testing/gtest/include/gtest/gtest.h" namespace { @@ -17,7 +17,7 @@ class RenderProcessTest : public testing::Test { virtual void SetUp() { // Need a MODE_SERVER to make MODE_CLIENTs (like a RenderThread) happy. channel_ = new IPC::Channel(kThreadName, IPC::Channel::MODE_SERVER, NULL); - render_process_.reset(new RenderProcessImpl); + render_process_.reset(new RenderProcess()); } virtual void TearDown() { @@ -34,7 +34,7 @@ class RenderProcessTest : public testing::Test { private: MessageLoopForIO message_loop_; - scoped_ptr<RenderProcessImpl> render_process_; + scoped_ptr<RenderProcess> render_process_; IPC::Channel *channel_; }; diff --git a/chrome/renderer/render_thread.cc b/chrome/renderer/render_thread.cc index eae2a80..8b7a98f 100644 --- a/chrome/renderer/render_thread.cc +++ b/chrome/renderer/render_thread.cc @@ -753,7 +753,7 @@ void RenderThread::EnsureWebKitInitialized() { } WebRuntimeFeatures::enableMediaPlayer( - RenderProcess::current()->HasInitializedMediaLibrary()); + RenderProcess::current()->initialized_media_library()); WebRuntimeFeatures::enableSockets( !command_line.HasSwitch(switches::kDisableWebSockets)); diff --git a/chrome/renderer/render_thread.h b/chrome/renderer/render_thread.h index 2aaf768..a7ad1fb 100644 --- a/chrome/renderer/render_thread.h +++ b/chrome/renderer/render_thread.h @@ -52,12 +52,6 @@ class WebStorageEventDispatcher; // The RenderThreadBase is the minimal interface that a RenderView/Widget // expects from a render thread. The interface basically abstracts a way to send // and receive messages. -// -// TODO(brettw) this should be refactored like RenderProcess/RenderProcessImpl: -// This class should be named RenderThread and the implementation below should -// be RenderThreadImpl. The ::current() getter on the impl should then be moved -// here so we can provide another implementation of RenderThread for tests -// without having to check for NULL all the time. class RenderThreadBase { public: virtual ~RenderThreadBase() {} @@ -97,10 +91,6 @@ class RenderThread : public RenderThreadBase, // Returns the one render thread for this process. Note that this should only // be accessed when running on the render thread itself - // - // TODO(brettw) this should be on the abstract base class instead of here, - // and return the base class' interface instead. Currently this causes - // problems with testing. See the comment above RenderThreadBase above. static RenderThread* current(); // Returns the routing ID of the RenderWidget containing the current script diff --git a/chrome/renderer/render_thread_unittest.cc b/chrome/renderer/render_thread_unittest.cc index 368e3d4..e22cabb 100644 --- a/chrome/renderer/render_thread_unittest.cc +++ b/chrome/renderer/render_thread_unittest.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2008 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. @@ -18,7 +18,7 @@ class RenderThreadTest : public testing::Test { virtual void SetUp() { // Need a MODE_SERVER to make MODE_CLIENTs (like a RenderThread) happy. channel_ = new IPC::Channel(kThreadName, IPC::Channel::MODE_SERVER, NULL); - mock_process_.reset(new MockRenderProcess); + mock_process_.reset(new MockProcess()); mock_process_->set_main_thread(new RenderThread(kThreadName)); } @@ -36,7 +36,7 @@ class RenderThreadTest : public testing::Test { protected: MessageLoop message_loop_; - scoped_ptr<MockRenderProcess> mock_process_; + scoped_ptr<MockProcess> mock_process_; IPC::Channel *channel_; }; diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc index 236cf87..892735f 100644 --- a/chrome/renderer/render_view.cc +++ b/chrome/renderer/render_view.cc @@ -53,7 +53,6 @@ #include "chrome/renderer/plugin_channel_host.h" #include "chrome/renderer/print_web_view_helper.h" #include "chrome/renderer/render_process.h" -#include "chrome/renderer/render_thread.h" #include "chrome/renderer/renderer_webstoragenamespace_impl.h" #include "chrome/renderer/spellchecker/spellcheck.h" #include "chrome/renderer/user_script_slave.h" @@ -1349,6 +1348,29 @@ void RenderView::OpenURL( // WebViewDelegate ------------------------------------------------------------ +void RenderView::DidPaint() { + WebFrame* main_frame = webview()->mainFrame(); + + if (main_frame->provisionalDataSource()) { + // If we have a provisional frame we are between the start + // and commit stages of loading...ignore this paint. + return; + } + + WebDataSource* ds = main_frame->dataSource(); + NavigationState* navigation_state = NavigationState::FromDataSource(ds); + DCHECK(navigation_state); + + Time now = Time::Now(); + if (navigation_state->first_paint_time().is_null()) { + navigation_state->set_first_paint_time(now); + } + if (navigation_state->first_paint_after_load_time().is_null() && + !navigation_state->finish_load_time().is_null()) { + navigation_state->set_first_paint_after_load_time(now); + } +} + void RenderView::LoadNavigationErrorPage(WebFrame* frame, const WebURLRequest& failed_request, const WebURLError& error, @@ -2962,7 +2984,7 @@ webkit_glue::WebPluginDelegate* RenderView::CreatePluginDelegate( mime_type_to_use = &mime_type; bool use_pepper_host = false; - bool in_process_plugin = RenderProcess::current()->UseInProcessPlugins(); + bool in_process_plugin = RenderProcess::current()->in_process_plugins(); // Check for trusted Pepper plugins. const char kPepperPrefix[] = "pepper-"; if (StartsWithASCII(*mime_type_to_use, kPepperPrefix, true)) { @@ -2984,10 +3006,10 @@ webkit_glue::WebPluginDelegate* RenderView::CreatePluginDelegate( } if (in_process_plugin) { if (use_pepper_host) { - WebPluginDelegatePepper* pepper_plugin = - WebPluginDelegatePepper::Create(path, *mime_type_to_use, - AsWeakPtr()); - current_pepper_plugins_.insert(pepper_plugin); + return WebPluginDelegatePepper::Create( + path, + *mime_type_to_use, + AsWeakPtr()); } else { #if defined(OS_WIN) // In-proc plugins aren't supported on Linux or Mac. return WebPluginDelegateImpl::Create( @@ -3446,17 +3468,6 @@ void RenderView::InsertCSS(const std::wstring& frame_xpath, web_frame->insertStyleText(WebString::fromUTF8(css), WebString::fromUTF8(id)); } -void RenderView::OnPepperPluginDestroy( - WebPluginDelegatePepper* pepper_plugin) { - std::set<WebPluginDelegatePepper*>::iterator found_pepper = - current_pepper_plugins_.find(pepper_plugin); - if (found_pepper == current_pepper_plugins_.end()) { - NOTREACHED(); - return; - } - current_pepper_plugins_.erase(found_pepper); -} - void RenderView::OnScriptEvalRequest(const std::wstring& frame_xpath, const std::wstring& jscript) { EvaluateScript(frame_xpath, jscript); @@ -3936,53 +3947,6 @@ void RenderView::OnResize(const gfx::Size& new_size, RenderWidget::OnResize(new_size, resizer_rect); } -void RenderView::DidInitiatePaint() { - // Notify any pepper plugins that we started painting. The plugin "should" - // never notified that we started painting, this is used for internal - // bookkeeping only, so we know that the set can not change under us. - for (std::set<WebPluginDelegatePepper*>::iterator i = - current_pepper_plugins_.begin(); - i != current_pepper_plugins_.end(); ++i) - (*i)->RenderViewInitiatedPaint(); -} - -void RenderView::DidFlushPaint() { - // Notify any pepper plugins that we painted. This will call into the plugin, - // and we it may ask to close itself as a result. This will, in turn, modify - // our set, possibly invalidating the iterator. So we iterate on a copy that - // won't change out from under us. - std::set<WebPluginDelegatePepper*> plugins = current_pepper_plugins_; - for (std::set<WebPluginDelegatePepper*>::iterator i = plugins.begin(); - i != plugins.end(); ++i) { - // The copy above makes sure our iterator is never invalid if some plugins - // are destroyed. But some plugin may decide to close all of its views in - // response to a paint in one of them, so we need to make sure each one is - // still "current" before using it. - if (current_pepper_plugins_.find(*i) != current_pepper_plugins_.end()) - (*i)->RenderViewFlushedPaint(); - } - - WebFrame* main_frame = webview()->mainFrame(); - - // If we have a provisional frame we are between the start and commit stages - // of loading and we don't want to save stats. - if (!main_frame->provisionalDataSource()) { - WebDataSource* ds = main_frame->dataSource(); - NavigationState* navigation_state = NavigationState::FromDataSource(ds); - DCHECK(navigation_state); - - Time now = Time::Now(); - if (navigation_state->first_paint_time().is_null()) { - navigation_state->set_first_paint_time(now); - } - if (navigation_state->first_paint_after_load_time().is_null() && - !navigation_state->finish_load_time().is_null()) { - navigation_state->set_first_paint_after_load_time(now); - } - } -} - - void RenderView::OnClearFocusedNode() { if (webview()) webview()->clearFocusedNode(); diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h index b2233bb..797402f 100644 --- a/chrome/renderer/render_view.h +++ b/chrome/renderer/render_view.h @@ -76,9 +76,7 @@ class GeolocationDispatcher; class GURL; class ListValue; class NavigationState; -class PepperDeviceTest; class PrintWebViewHelper; -class WebPluginDelegatePepper; class WebPluginDelegateProxy; struct ContextMenuMediaParams; struct ThumbnailScore; @@ -441,11 +439,6 @@ class RenderView : public RenderWidget, const std::string& css, const std::string& id); - // Informs us that the given pepper plugin we created is being deleted the - // pointer must not be dereferenced as this is called from the destructor of - // the plugin. - void OnPepperPluginDestroy(WebPluginDelegatePepper* pepper_plugin); - // Whether content state (such as form state and scroll position) should be // sent to the browser immediately. This is normally false, but set to true // by some tests. @@ -498,8 +491,7 @@ class RenderView : public RenderWidget, virtual void Close(); virtual void OnResize(const gfx::Size& new_size, const gfx::Rect& resizer_rect); - virtual void DidInitiatePaint(); - virtual void DidFlushPaint(); + virtual void DidPaint(); virtual void DidHandleKeyEvent(); #if OS_MACOSX virtual void OnSetFocus(bool enable); @@ -510,7 +502,6 @@ class RenderView : public RenderWidget, private: // For unit tests. friend class RenderViewTest; - friend class PepperDeviceTest; FRIEND_TEST(RenderViewTest, OnLoadAlternateHTMLText); FRIEND_TEST(RenderViewTest, OnNavStateChanged); FRIEND_TEST(RenderViewTest, OnImeStateChanged); @@ -1145,10 +1136,6 @@ class RenderView : public RenderWidget, TextTranslatorImpl text_translator_; scoped_ptr<PageTranslator> page_translator_; - // A list of all pepper plugins that we've created that haven't been - // destroyed yet. - std::set<WebPluginDelegatePepper*> current_pepper_plugins_; - // The FormManager for this RenderView. FormManager form_manager_; diff --git a/chrome/renderer/render_widget.cc b/chrome/renderer/render_widget.cc index 03fbbd7..343db541 100644 --- a/chrome/renderer/render_widget.cc +++ b/chrome/renderer/render_widget.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2009 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. @@ -15,7 +15,6 @@ #include "chrome/common/render_messages.h" #include "chrome/common/transport_dib.h" #include "chrome/renderer/render_process.h" -#include "chrome/renderer/render_thread.h" #include "skia/ext/platform_canvas.h" #include "third_party/skia/include/core/SkShader.h" #include "third_party/WebKit/WebKit/chromium/public/WebCursorInfo.h" @@ -271,8 +270,8 @@ void RenderWidget::OnUpdateRectAck() { current_paint_buf_ = NULL; } - // Notify subclasses. - DidFlushPaint(); + // Notify subclasses + DidPaint(); // Continue painting if necessary... CallDoDeferredUpdate(); @@ -498,9 +497,6 @@ void RenderWidget::DoDeferredUpdate() { next_paint_flags_ = 0; UpdateIME(); - - // Let derived classes know we've painted. - DidInitiatePaint(); } /////////////////////////////////////////////////////////////////////////////// diff --git a/chrome/renderer/render_widget.h b/chrome/renderer/render_widget.h index dab2a81..ab591f0 100644 --- a/chrome/renderer/render_widget.h +++ b/chrome/renderer/render_widget.h @@ -161,12 +161,9 @@ class RenderWidget : public IPC::Channel::Listener, void OnMsgRepaint(const gfx::Size& size_to_paint); void OnSetTextDirection(WebKit::WebTextDirection direction); - // Override point to notify derived classes that a paint has happened. - // DidInitiatePaint happens when we've generated a new bitmap and sent it to - // the browser. DidFlushPaint happens once we've received the ACK that the - // screen has actually been updated. - virtual void DidInitiatePaint() {} - virtual void DidFlushPaint() {} + // Override point to notify that a paint has happened. This fires after the + // browser side has updated the screen for a newly painted region. + virtual void DidPaint() {} // Sets the "hidden" state of this widget. All accesses to is_hidden_ should // use this method so that we can properly inform the RenderThread of our diff --git a/chrome/renderer/render_widget_unittest.cc b/chrome/renderer/render_widget_unittest.cc index 5808bc0..b649725f 100644 --- a/chrome/renderer/render_widget_unittest.cc +++ b/chrome/renderer/render_widget_unittest.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2006-2008 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. @@ -28,7 +28,7 @@ class RenderWidgetTest : public testing::Test { private: // testing::Test virtual void SetUp() { - mock_process_.reset(new MockRenderProcess); + mock_process_.reset(new MockProcess()); render_thread_.set_routing_id(kRouteId); widget_ = RenderWidget::Create(kOpenerId, &render_thread_, true); ASSERT_TRUE(widget_); @@ -38,7 +38,7 @@ class RenderWidgetTest : public testing::Test { mock_process_.reset(); } - scoped_ptr<MockRenderProcess> mock_process_; + scoped_ptr<MockProcess> mock_process_; }; TEST_F(RenderWidgetTest, CreateAndCloseWidget) { diff --git a/chrome/renderer/renderer_main.cc b/chrome/renderer/renderer_main.cc index 2556ba7..d4e2c5f 100644 --- a/chrome/renderer/renderer_main.cc +++ b/chrome/renderer/renderer_main.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2006-2008 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. @@ -23,7 +23,7 @@ #include "chrome/common/main_function_params.h" #include "chrome/common/net/net_resource_provider.h" #include "chrome/renderer/renderer_main_platform_delegate.h" -#include "chrome/renderer/render_process_impl.h" +#include "chrome/renderer/render_process.h" #include "chrome/renderer/render_thread.h" #include "grit/generated_resources.h" #include "net/base/net_module.h" @@ -219,7 +219,7 @@ int RendererMain(const MainFunctionParams& parameters) { #else // The main message loop of the renderer services doesn't have IO or UI tasks, // unless in-process-plugins is used. - MessageLoop main_message_loop(RenderProcessImpl::InProcessPlugins() ? + MessageLoop main_message_loop(RenderProcess::InProcessPlugins() ? MessageLoop::TYPE_UI : MessageLoop::TYPE_DEFAULT); #endif @@ -255,7 +255,7 @@ int RendererMain(const MainFunctionParams& parameters) { #if !defined(OS_LINUX) // TODO(markus): Check if it is OK to unconditionally move this // instruction down. - RenderProcessImpl render_process; + RenderProcess render_process; render_process.set_main_thread(new RenderThread()); #endif bool run_loop = true; @@ -263,7 +263,7 @@ int RendererMain(const MainFunctionParams& parameters) { run_loop = platform.EnableSandbox(); } #if defined(OS_LINUX) - RenderProcessImpl render_process; + RenderProcess render_process; render_process.set_main_thread(new RenderThread()); #endif diff --git a/chrome/renderer/webplugin_delegate_pepper.cc b/chrome/renderer/webplugin_delegate_pepper.cc index 0d235c9..10c66cd 100644 --- a/chrome/renderer/webplugin_delegate_pepper.cc +++ b/chrome/renderer/webplugin_delegate_pepper.cc @@ -217,24 +217,6 @@ FilePath WebPluginDelegatePepper::GetPluginPath() { return instance()->plugin_lib()->plugin_info().path; } -void WebPluginDelegatePepper::RenderViewInitiatedPaint() { - // Broadcast event to all 2D contexts. - Graphics2DMap::iterator iter2d(&graphic2d_contexts_); - while (!iter2d.IsAtEnd()) { - iter2d.GetCurrentValue()->RenderViewInitiatedPaint(); - iter2d.Advance(); - } -} - -void WebPluginDelegatePepper::RenderViewFlushedPaint() { - // Broadcast event to all 2D contexts. - Graphics2DMap::iterator iter2d(&graphic2d_contexts_); - while (!iter2d.IsAtEnd()) { - iter2d.GetCurrentValue()->RenderViewFlushedPaint(); - iter2d.Advance(); - } -} - WebPluginResourceClient* WebPluginDelegatePepper::CreateResourceClient( unsigned long resource_id, const GURL& url, int notify_id) { return instance()->CreateStream(resource_id, url, std::string(), notify_id); @@ -269,7 +251,7 @@ NPError WebPluginDelegatePepper::Device2DInitializeContext( // it will have a window handle. plugin_->SetWindow(NULL); - scoped_ptr<Graphics2DDeviceContext> g2d(new Graphics2DDeviceContext(this)); + scoped_ptr<Graphics2DDeviceContext> g2d(new Graphics2DDeviceContext()); NPError status = g2d->Initialize(window_rect_, config, context); if (NPERR_NO_ERROR == status) { context->reserved = reinterpret_cast<void *>( @@ -655,9 +637,6 @@ WebPluginDelegatePepper::WebPluginDelegatePepper( WebPluginDelegatePepper::~WebPluginDelegatePepper() { DestroyInstance(); - - if (render_view_) - render_view_->OnPepperPluginDestroy(this); } void WebPluginDelegatePepper::ForwardSetWindow() { diff --git a/chrome/renderer/webplugin_delegate_pepper.h b/chrome/renderer/webplugin_delegate_pepper.h index 8364a60..a67b530 100644 --- a/chrome/renderer/webplugin_delegate_pepper.h +++ b/chrome/renderer/webplugin_delegate_pepper.h @@ -37,8 +37,6 @@ class WebPluginDelegatePepper : public webkit_glue::WebPluginDelegate { const std::string& mime_type, const base::WeakPtr<RenderView>& render_view); - NPAPI::PluginInstance* instance() { return instance_.get(); } - // WebPluginDelegate implementation virtual bool Initialize(const GURL& url, const std::vector<std::string>& arg_names, @@ -146,12 +144,6 @@ class WebPluginDelegatePepper : public webkit_glue::WebPluginDelegate { // Returns the path for the library implementing this plugin. FilePath GetPluginPath(); - // Notifications when the RenderView painted the screen (InitiatedPaint) and - // when an ack was received that the browser copied it to the screen - // (FlushedPaint). - void RenderViewInitiatedPaint(); - void RenderViewFlushedPaint(); - private: WebPluginDelegatePepper( const base::WeakPtr<RenderView>& render_view, @@ -165,6 +157,8 @@ class WebPluginDelegatePepper : public webkit_glue::WebPluginDelegate { //----------------------------------------- // used for windowed and windowless plugins + NPAPI::PluginInstance* instance() { return instance_.get(); } + // Closes down and destroys our plugin instance. void DestroyInstance(); @@ -197,8 +191,7 @@ class WebPluginDelegatePepper : public webkit_glue::WebPluginDelegate { std::vector<gfx::Rect> cutout_rects_; // Open device contexts - typedef IDMap<Graphics2DDeviceContext, IDMapOwnPointer> Graphics2DMap; - Graphics2DMap graphic2d_contexts_; + IDMap<Graphics2DDeviceContext, IDMapOwnPointer> graphic2d_contexts_; IDMap<AudioDeviceContext, IDMapOwnPointer> audio_contexts_; // Plugin graphics context implementation diff --git a/chrome/test/render_view_test.cc b/chrome/test/render_view_test.cc index f920a2f..001e7b1 100644 --- a/chrome/test/render_view_test.cc +++ b/chrome/test/render_view_test.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2009 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. @@ -13,7 +13,6 @@ #include "chrome/renderer/extensions/extension_process_bindings.h" #include "chrome/renderer/extensions/js_only_v8_extensions.h" #include "chrome/renderer/extensions/renderer_extension_bindings.h" -#include "chrome/renderer/mock_render_process.h" #include "chrome/renderer/renderer_main_platform_delegate.h" #include "third_party/WebKit/WebKit/chromium/public/WebFrame.h" #include "third_party/WebKit/WebKit/chromium/public/WebInputEvent.h" @@ -35,12 +34,6 @@ const int32 kRouteId = 5; const int32 kOpenerId = 7; } // namespace -RenderViewTest::RenderViewTest() { -} - -RenderViewTest::~RenderViewTest() { -} - void RenderViewTest::ProcessPendingMessages() { msg_loop_.PostTask(FROM_HERE, new MessageLoop::QuitTask()); msg_loop_.Run(); @@ -96,7 +89,7 @@ void RenderViewTest::SetUp() { Extension::kPermissionNames + Extension::kNumPermissions); ExtensionProcessBindings::SetAPIPermissions("", permissions); - mock_process_.reset(new MockRenderProcess); + mock_process_.reset(new MockProcess()); render_thread_.set_routing_id(kRouteId); @@ -109,7 +102,6 @@ void RenderViewTest::SetUp() { // Attach a pseudo keyboard device to this object. mock_keyboard_.reset(new MockKeyboard()); } - void RenderViewTest::TearDown() { // Try very hard to collect garbage before shutting down. GetMainFrame()->collectGarbage(); diff --git a/chrome/test/render_view_test.h b/chrome/test/render_view_test.h index 6a36097..add9d55 100644 --- a/chrome/test/render_view_test.h +++ b/chrome/test/render_view_test.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2009 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. @@ -13,6 +13,7 @@ #include "chrome/common/native_web_keyboard_event.h" #include "chrome/common/sandbox_init_wrapper.h" #include "chrome/renderer/mock_keyboard.h" +#include "chrome/renderer/mock_render_process.h" #include "chrome/renderer/mock_render_thread.h" #include "chrome/renderer/render_view.h" #include "chrome/renderer/renderer_main_platform_delegate.h" @@ -20,12 +21,10 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/WebKit/WebKit/chromium/public/WebFrame.h" -class MockRenderProcess; - class RenderViewTest : public testing::Test { public: - RenderViewTest(); - ~RenderViewTest(); + RenderViewTest() {} + ~RenderViewTest() {} protected: // Spins the message loop to process all messages that are currently pending. @@ -57,7 +56,7 @@ class RenderViewTest : public testing::Test { MessageLoop msg_loop_; MockRenderThread render_thread_; - scoped_ptr<MockRenderProcess> mock_process_; + scoped_ptr<MockProcess> mock_process_; scoped_refptr<RenderView> view_; RendererWebKitClientImpl webkitclient_; scoped_ptr<MockKeyboard> mock_keyboard_; diff --git a/gpu/gpu_plugin/gpu_plugin.h b/gpu/gpu_plugin/gpu_plugin.h index 05c98a9..b973d7cf 100644 --- a/gpu/gpu_plugin/gpu_plugin.h +++ b/gpu/gpu_plugin/gpu_plugin.h @@ -19,7 +19,7 @@ NPError API_CALL NP_GetEntryPoints(NPPluginFuncs* funcs); #if defined(OS_POSIX) && !defined(OS_MACOSX) NPError API_CALL NP_Initialize(NPNetscapeFuncs *browser_funcs, - NPPluginFuncs* plugin_funcs); + NPPluginFuncs* plugin_funcs); #else NPError API_CALL NP_Initialize(NPNetscapeFuncs* browser_funcs); #endif diff --git a/webkit/glue/plugins/plugin_list.cc b/webkit/glue/plugins/plugin_list.cc index 3994f15..f7643b4 100644 --- a/webkit/glue/plugins/plugin_list.cc +++ b/webkit/glue/plugins/plugin_list.cc @@ -58,17 +58,6 @@ void PluginList::RegisterInternalPlugin(const PluginVersionInfo& info) { internal_plugins_.push_back(info); } -void PluginList::UnregisterInternalPlugin(const FilePath& path) { - AutoLock lock(lock_); - for (size_t i = 0; i < internal_plugins_.size(); i++) { - if (internal_plugins_[i].path == path) { - internal_plugins_.erase(internal_plugins_.begin() + i); - return; - } - } - NOTREACHED(); -} - bool PluginList::ReadPluginInfo(const FilePath &filename, WebPluginInfo* info, const PluginEntryPoints** entry_points) { diff --git a/webkit/glue/plugins/plugin_list.h b/webkit/glue/plugins/plugin_list.h index c920397..dea1ab9 100644 --- a/webkit/glue/plugins/plugin_list.h +++ b/webkit/glue/plugins/plugin_list.h @@ -91,12 +91,6 @@ class PluginList { // be loaded using PluginList::LoadPlugin(). void RegisterInternalPlugin(const PluginVersionInfo& info); - // Removes a specified internal plugin from the list. The search will match - // on the path from the version info previously registered. - // - // This is generally only necessary for tests. - void UnregisterInternalPlugin(const FilePath& path); - // Creates a WebPluginInfo structure given a plugin's path. On success // returns true, with the information being put into "info". If it's an // internal plugin, "entry_points" is filled in as well with a |