diff options
-rw-r--r-- | webkit/glue/plugins/webplugin_delegate_impl.cc | 104 | ||||
-rw-r--r-- | webkit/glue/plugins/webplugin_delegate_impl.h | 12 |
2 files changed, 58 insertions, 58 deletions
diff --git a/webkit/glue/plugins/webplugin_delegate_impl.cc b/webkit/glue/plugins/webplugin_delegate_impl.cc index 3abcbd6..12333ae 100644 --- a/webkit/glue/plugins/webplugin_delegate_impl.cc +++ b/webkit/glue/plugins/webplugin_delegate_impl.cc @@ -8,6 +8,8 @@ #include <vector> #include "base/file_util.h" +#include "base/iat_patch.h" +#include "base/lazy_instance.h" #include "base/message_loop.h" #include "base/stats_counters.h" #include "base/string_util.h" @@ -21,14 +23,13 @@ #include "webkit/glue/plugins/plugin_stream_url.h" #include "webkit/glue/webkit_glue.h" -static StatsCounter windowless_queue("Plugin.ThrottleQueue"); +namespace { -static const wchar_t kWebPluginDelegateProperty[] = - L"WebPluginDelegateProperty"; -static const wchar_t kPluginNameAtomProperty[] = L"PluginNameAtom"; -static const wchar_t kDummyActivationWindowName[] = L"DummyWindowForActivation"; -static const wchar_t kPluginOrigProc[] = L"OriginalPtr"; -static const wchar_t kPluginFlashThrottle[] = L"FlashThrottle"; +const wchar_t kWebPluginDelegateProperty[] = L"WebPluginDelegateProperty"; +const wchar_t kPluginNameAtomProperty[] = L"PluginNameAtom"; +const wchar_t kDummyActivationWindowName[] = L"DummyWindowForActivation"; +const wchar_t kPluginOrigProc[] = L"OriginalPtr"; +const wchar_t kPluginFlashThrottle[] = L"FlashThrottle"; // The fastest we are willing to process WM_USER+1 events for Flash. // Flash can easily exceed the limits of our CPU if we don't throttle it. @@ -39,14 +40,22 @@ static const wchar_t kPluginFlashThrottle[] = L"FlashThrottle"; // time currently required to paint Flash plugins. There isn't a good // way to count the time spent in aggregate plugin painting, however, so // this seems to work well enough. -static const int kFlashWMUSERMessageThrottleDelayMs = 5; +const int kFlashWMUSERMessageThrottleDelayMs = 5; -std::list<MSG> WebPluginDelegateImpl::throttle_queue_; +// The current instance of the plugin which entered the modal loop. +WebPluginDelegateImpl* g_current_plugin_instance = NULL; -WebPluginDelegateImpl* WebPluginDelegateImpl::current_plugin_instance_ = NULL; +base::LazyInstance<std::list<MSG> > g_throttle_queue(base::LINKER_INITIALIZED); -iat_patch::IATPatchFunction WebPluginDelegateImpl::iat_patch_track_popup_menu_; -iat_patch::IATPatchFunction WebPluginDelegateImpl::iat_patch_set_cursor_; +// Helper object for patching the TrackPopupMenu API. +base::LazyInstance<iat_patch::IATPatchFunction> g_iat_patch_track_popup_menu( + base::LINKER_INITIALIZED); + +// Helper object for patching the SetCursor API. +base::LazyInstance<iat_patch::IATPatchFunction> g_iat_patch_set_cursor( + base::LINKER_INITIALIZED); + +} // namespace WebPluginDelegateImpl* WebPluginDelegateImpl::Create( const FilePath& filename, @@ -112,8 +121,8 @@ bool WebPluginDelegateImpl::IsDummyActivationWindow(HWND window) { LRESULT CALLBACK WebPluginDelegateImpl::HandleEventMessageFilterHook( int code, WPARAM wParam, LPARAM lParam) { - DCHECK(current_plugin_instance_); - current_plugin_instance_->OnModalLoopEntered(); + DCHECK(g_current_plugin_instance); + g_current_plugin_instance->OnModalLoopEntered(); return CallNextHookEx(NULL, code, wParam, lParam); } @@ -261,9 +270,9 @@ bool WebPluginDelegateImpl::Initialize(const GURL& url, // lives on the browser thread. Our workaround is to intercept the // TrackPopupMenu API for Silverlight and replace the window handle // with the dummy activation window. - if (windowless_ && !iat_patch_track_popup_menu_.is_patched() && + if (windowless_ && !g_iat_patch_track_popup_menu.Pointer()->is_patched() && (quirks_ & PLUGIN_QUIRK_PATCH_TRACKPOPUP_MENU)) { - iat_patch_track_popup_menu_.Patch( + g_iat_patch_track_popup_menu.Pointer()->Patch( plugin_module_handle_, "user32.dll", "TrackPopupMenu", WebPluginDelegateImpl::TrackPopupMenuPatch); } @@ -274,11 +283,11 @@ bool WebPluginDelegateImpl::Initialize(const GURL& url, // and remember the cursor being set. This is shipped over to the browser // in the HandleEvent call, which ensures that the cursor does not change // when a windowless plugin instance changes the cursor in a background tab. - if (windowless_ && !iat_patch_set_cursor_.is_patched() && + if (windowless_ && !g_iat_patch_set_cursor.Pointer()->is_patched() && (quirks_ & PLUGIN_QUIRK_PATCH_SETCURSOR)) { - iat_patch_set_cursor_.Patch(plugin_module_handle_, "user32.dll", - "SetCursor", - WebPluginDelegateImpl::SetCursorPatch); + g_iat_patch_set_cursor.Pointer()->Patch( + plugin_module_handle_, "user32.dll", "SetCursor", + WebPluginDelegateImpl::SetCursorPatch); } return true; } @@ -303,12 +312,12 @@ void WebPluginDelegateImpl::DestroyInstance() { if (instance_->plugin_lib()) { // Unpatch if this is the last plugin instance. if (instance_->plugin_lib()->instance_count() == 1) { - if (iat_patch_set_cursor_.is_patched()) { - iat_patch_set_cursor_.Unpatch(); + if (g_iat_patch_set_cursor.Pointer()->is_patched()) { + g_iat_patch_set_cursor.Pointer()->Unpatch(); } - if (iat_patch_track_popup_menu_.is_patched()) { - iat_patch_track_popup_menu_.Unpatch(); + if (g_iat_patch_track_popup_menu.Pointer()->is_patched()) { + g_iat_patch_track_popup_menu.Pointer()->Unpatch(); } } } @@ -504,11 +513,12 @@ void WebPluginDelegateImpl::WindowedDestroyWindow() { // the queue. // static void WebPluginDelegateImpl::ClearThrottleQueueForWindow(HWND window) { + std::list<MSG>* throttle_queue = g_throttle_queue.Pointer(); + std::list<MSG>::iterator it; - for (it = throttle_queue_.begin(); it != throttle_queue_.end(); ) { + for (it = throttle_queue->begin(); it != throttle_queue->end(); ) { if (it->hwnd == window) { - it = throttle_queue_.erase(it); - windowless_queue.Decrement(); + it = throttle_queue->erase(it); } else { it++; } @@ -523,10 +533,11 @@ void WebPluginDelegateImpl::OnThrottleMessage() { // message it finds for each plugin. It is important to service // all active plugins with each pass through the throttle, otherwise // we see video jankiness. + std::list<MSG>* throttle_queue = g_throttle_queue.Pointer(); std::map<HWND, int> processed; - std::list<MSG>::iterator it = throttle_queue_.begin(); - while (it != throttle_queue_.end()) { + std::list<MSG>::iterator it = throttle_queue->begin(); + while (it != throttle_queue->end()) { const MSG& msg = *it; if (processed.find(msg.hwnd) == processed.end()) { WNDPROC proc = reinterpret_cast<WNDPROC>(msg.time); @@ -536,14 +547,13 @@ void WebPluginDelegateImpl::OnThrottleMessage() { if (IsWindow(msg.hwnd)) CallWindowProc(proc, msg.hwnd, msg.message, msg.wParam, msg.lParam); processed[msg.hwnd] = 1; - it = throttle_queue_.erase(it); - windowless_queue.Decrement(); + it = throttle_queue->erase(it); } else { it++; } } - if (throttle_queue_.size() > 0) + if (throttle_queue->size() > 0) MessageLoop::current()->PostDelayedTask(FROM_HERE, NewRunnableFunction(&WebPluginDelegateImpl::OnThrottleMessage), kFlashWMUSERMessageThrottleDelayMs); @@ -560,10 +570,12 @@ void WebPluginDelegateImpl::ThrottleMessage(WNDPROC proc, HWND hwnd, msg.message = message; msg.wParam = wParam; msg.lParam = lParam; - throttle_queue_.push_back(msg); - windowless_queue.Increment(); - if (throttle_queue_.size() == 1) { + std::list<MSG>* throttle_queue = g_throttle_queue.Pointer(); + + throttle_queue->push_back(msg); + + if (throttle_queue->size() == 1) { MessageLoop::current()->PostDelayedTask(FROM_HERE, NewRunnableFunction(&WebPluginDelegateImpl::OnThrottleMessage), kFlashWMUSERMessageThrottleDelayMs); @@ -815,7 +827,7 @@ LRESULT CALLBACK WebPluginDelegateImpl::NativeWndProc( return FALSE; } - current_plugin_instance_ = delegate; + g_current_plugin_instance = delegate; switch (message) { case WM_NCDESTROY: { @@ -834,7 +846,7 @@ LRESULT CALLBACK WebPluginDelegateImpl::NativeWndProc( if (delegate->quirks() & PLUGIN_QUIRK_THROTTLE_WM_USER_PLUS_ONE) { WebPluginDelegateImpl::ThrottleMessage(delegate->plugin_wnd_proc_, hwnd, message, wparam, lparam); - current_plugin_instance_ = NULL; + g_current_plugin_instance = NULL; return FALSE; } break; @@ -861,7 +873,7 @@ LRESULT CALLBACK WebPluginDelegateImpl::NativeWndProc( LRESULT result = CallWindowProc(delegate->plugin_wnd_proc_, hwnd, message, wparam, lparam); delegate->is_calling_wndproc = false; - current_plugin_instance_ = NULL; + g_current_plugin_instance = NULL; return result; } @@ -1003,7 +1015,7 @@ bool WebPluginDelegateImpl::HandleEvent(NPEvent* event, bool old_task_reentrancy_state = MessageLoop::current()->NestableTasksAllowed(); - current_plugin_instance_ = this; + g_current_plugin_instance = this; handle_event_depth_++; @@ -1029,7 +1041,7 @@ bool WebPluginDelegateImpl::HandleEvent(NPEvent* event, handle_event_depth_--; - current_plugin_instance_ = NULL; + g_current_plugin_instance = NULL; MessageLoop::current()->SetNestableTasksAllowed(old_task_reentrancy_state); @@ -1125,14 +1137,14 @@ void WebPluginDelegateImpl::OnUserGestureEnd() { BOOL WINAPI WebPluginDelegateImpl::TrackPopupMenuPatch( HMENU menu, unsigned int flags, int x, int y, int reserved, HWND window, const RECT* rect) { - if (current_plugin_instance_) { + if (g_current_plugin_instance) { unsigned long window_process_id = 0; unsigned long window_thread_id = GetWindowThreadProcessId(window, &window_process_id); // TrackPopupMenu fails if the window passed in belongs to a different // thread. if (::GetCurrentThreadId() != window_thread_id) { - window = current_plugin_instance_->dummy_window_for_activation_; + window = g_current_plugin_instance->dummy_window_for_activation_; } } return TrackPopupMenu(menu, flags, x, y, reserved, window, rect); @@ -1143,19 +1155,19 @@ HCURSOR WINAPI WebPluginDelegateImpl::SetCursorPatch(HCURSOR cursor) { // instantiated on the plugin thread. This causes annoying cursor flicker // when the mouse is moved on a foreground tab, with a windowless plugin // instance in a background tab. We just ignore the call here. - if (!current_plugin_instance_) + if (!g_current_plugin_instance) return GetCursor(); - if (!current_plugin_instance_->windowless()) { + if (!g_current_plugin_instance->windowless()) { return SetCursor(cursor); } // It is ok to pass NULL here to GetCursor as we are not looking for cursor // types defined by Webkit. HCURSOR previous_cursor = - current_plugin_instance_->current_windowless_cursor_.GetCursor(NULL); + g_current_plugin_instance->current_windowless_cursor_.GetCursor(NULL); - current_plugin_instance_->current_windowless_cursor_.InitFromExternalCursor( + g_current_plugin_instance->current_windowless_cursor_.InitFromExternalCursor( cursor); return previous_cursor; } diff --git a/webkit/glue/plugins/webplugin_delegate_impl.h b/webkit/glue/plugins/webplugin_delegate_impl.h index d01046c..fcb849d 100644 --- a/webkit/glue/plugins/webplugin_delegate_impl.h +++ b/webkit/glue/plugins/webplugin_delegate_impl.h @@ -10,7 +10,6 @@ #include "base/file_path.h" #include "base/gfx/native_widget_types.h" -#include "base/iat_patch.h" #include "base/ref_counted.h" #include "base/task.h" #include "third_party/npapi/bindings/npapi.h" @@ -203,8 +202,6 @@ class WebPluginDelegateImpl : public WebPluginDelegate { HWND dummy_window_for_activation_; bool CreateDummyWindowForActivation(); - static std::list<MSG> throttle_queue_; - // Returns true if the event passed in needs to be tracked for a potential // modal loop. static bool ShouldTrackEventForModalLoops(NPEvent* event); @@ -226,9 +223,6 @@ class WebPluginDelegateImpl : public WebPluginDelegate { // Handle to the message filter hook HHOOK handle_event_message_filter_hook_; - // The current instance of the plugin which entered the modal loop. - static WebPluginDelegateImpl* current_plugin_instance_; - // Event which is set when the plugin enters a modal loop in the course // of a NPP_HandleEvent call. HANDLE handle_event_pump_messages_event_; @@ -249,9 +243,6 @@ class WebPluginDelegateImpl : public WebPluginDelegate { // The plugin module handle. HMODULE plugin_module_handle_; - // Helper object for patching the TrackPopupMenu API - static iat_patch::IATPatchFunction iat_patch_track_popup_menu_; - // TrackPopupMenu interceptor. Parameters are the same as the Win32 function // TrackPopupMenu. static BOOL WINAPI TrackPopupMenuPatch(HMENU menu, unsigned int flags, int x, @@ -261,9 +252,6 @@ class WebPluginDelegateImpl : public WebPluginDelegate { // SetCursor interceptor for windowless plugins. static HCURSOR WINAPI SetCursorPatch(HCURSOR cursor); - // Helper object for patching the SetCursor API - static iat_patch::IATPatchFunction iat_patch_set_cursor_; - // Holds the current cursor set by the windowless plugin. WebCursor current_windowless_cursor_; |