Bug 722315 - Increase Firefox startup speed on Windows by lazy loading CLSID_DragDropHelper. r=jimm
authorBrian R. Bondy <netzen@gmail.com>
Wed, 01 Feb 2012 09:30:05 -0500
changeset 86073 740c10e98e7c0f14ecafbf8d70a9226f4f59f838
parent 86072 738e02c121ae550e6be9c30a11dbc2e928e68cc4
child 86074 77b586e22cb6e44b0181b720d5b936ab56a17678
push id94
push userbturner@mozilla.com
push dateWed, 08 Feb 2012 05:39:15 +0000
reviewersjimm
bugs722315
milestone13.0a1
Bug 722315 - Increase Firefox startup speed on Windows by lazy loading CLSID_DragDropHelper. r=jimm
widget/windows/nsNativeDragTarget.cpp
widget/windows/nsNativeDragTarget.h
--- a/widget/windows/nsNativeDragTarget.cpp
+++ b/widget/windows/nsNativeDragTarget.cpp
@@ -67,20 +67,16 @@ nsNativeDragTarget::nsNativeDragTarget(n
     mTookOwnRef(false), mWindow(aWnd), mDropTargetHelper(nsnull)
 {
   mHWnd = (HWND)mWindow->GetNativeData(NS_NATIVE_WINDOW);
 
   /*
    * Create/Get the DragService that we have implemented
    */
   CallGetService(kCDragServiceCID, &mDragService);
-
-  // Drag target helper for drag image support
-  CoCreateInstance(CLSID_DragDropHelper, NULL, CLSCTX_INPROC_SERVER,
-                   IID_IDropTargetHelper, (LPVOID*)&mDropTargetHelper);
 }
 
 nsNativeDragTarget::~nsNativeDragTarget()
 {
   NS_RELEASE(mDragService);
 
   if (mDropTargetHelper) {
     mDropTargetHelper->Release();
@@ -260,19 +256,19 @@ nsNativeDragTarget::DragEnter(LPDATAOBJE
   if (!mDragService) {
     return E_FAIL;
   }
 
   mEffectsAllowed = *pdwEffect;
   AddLinkSupportIfCanBeGenerated(pIDataSource);
 
   // Drag and drop image helper
-  if (mDropTargetHelper) {
+  if (GetDropTargetHelper()) {
     POINT pt = { ptl.x, ptl.y };
-    mDropTargetHelper->DragEnter(mHWnd, pIDataSource, &pt, *pdwEffect);
+    GetDropTargetHelper()->DragEnter(mHWnd, pIDataSource, &pt, *pdwEffect);
   }
 
   // save a ref to this, in case the window is destroyed underneath us
   NS_ASSERTION(!mTookOwnRef, "own ref already taken!");
   this->AddRef();
   mTookOwnRef = true;
 
   // tell the drag service about this drag (it may have come from an
@@ -336,19 +332,19 @@ nsNativeDragTarget::DragOver(DWORD   grf
   if (!currentDragSession) {
     return S_OK;  // Drag was canceled.
   }
 
   // without the AddRef() |this| can get destroyed in an event handler
   this->AddRef();
 
   // Drag and drop image helper
-  if (mDropTargetHelper) {
+  if (GetDropTargetHelper()) {
     POINT pt = { ptl.x, ptl.y };
-    mDropTargetHelper->DragOver(&pt, *pdwEffect);
+    GetDropTargetHelper()->DragOver(&pt, *pdwEffect);
   }
 
   mDragService->FireDragEventAtSource(NS_DRAGDROP_DRAG);
   // Now process the native drag state and then dispatch the event
   ProcessDrag(NS_DRAGDROP_OVER, grfKeyState, ptl, pdwEffect);
 
   this->Release();
 
@@ -358,18 +354,18 @@ nsNativeDragTarget::DragOver(DWORD   grf
 STDMETHODIMP
 nsNativeDragTarget::DragLeave()
 {
   if (!mDragService) {
     return E_FAIL;
   }
 
   // Drag and drop image helper
-  if (mDropTargetHelper) {
-    mDropTargetHelper->DragLeave();
+  if (GetDropTargetHelper()) {
+    GetDropTargetHelper()->DragLeave();
   }
 
   // dispatch the event into Gecko
   DispatchDragDropEvent(NS_DRAGDROP_EXIT, gDragLastPoint);
 
   nsCOMPtr<nsIDragSession> currentDragSession;
   mDragService->GetCurrentSession(getter_AddRefs(currentDragSession));
 
@@ -396,18 +392,18 @@ nsNativeDragTarget::DragLeave()
   return S_OK;
 }
 
 void
 nsNativeDragTarget::DragCancel()
 {
   // Cancel the drag session if we did DragEnter.
   if (mTookOwnRef) {
-    if (mDropTargetHelper) {
-      mDropTargetHelper->DragLeave();
+    if (GetDropTargetHelper()) {
+      GetDropTargetHelper()->DragLeave();
     }
     if (mDragService) {
       mDragService->EndDragSession(false);
     }
     this->Release(); // matching the AddRef in DragEnter
     mTookOwnRef = false;
   }
 }
@@ -421,19 +417,19 @@ nsNativeDragTarget::Drop(LPDATAOBJECT pD
   if (!mDragService) {
     return E_FAIL;
   }
 
   mEffectsAllowed = *pdwEffect;
   AddLinkSupportIfCanBeGenerated(pData);
 
   // Drag and drop image helper
-  if (mDropTargetHelper) {
+  if (GetDropTargetHelper()) {
     POINT pt = { aPT.x, aPT.y };
-    mDropTargetHelper->Drop(pData, &pt, *pdwEffect);
+    GetDropTargetHelper()->Drop(pData, &pt, *pdwEffect);
   }
 
   // Set the native data object into the drag service
   //
   // This cast is ok because in the constructor we created a
   // the actual implementation we wanted, so we know this is
   // a nsDragService (but it should still be a private interface)
   nsDragService* winDragService = static_cast<nsDragService*>(mDragService);
@@ -472,8 +468,23 @@ nsNativeDragTarget::Drop(LPDATAOBJECT pD
   NS_ASSERTION(mTookOwnRef, "want to release own ref, but not taken!");
   if (mTookOwnRef) {
     this->Release();
     mTookOwnRef = false;
   }
 
   return S_OK;
 }
+
+/**
+ * By lazy loading mDropTargetHelper we save 50-70ms of startup time
+ * which is ~5% of startup time.
+*/
+IDropTargetHelper*
+nsNativeDragTarget::GetDropTargetHelper()
+{
+  if (!mDropTargetHelper) { 
+    CoCreateInstance(CLSID_DragDropHelper, NULL, CLSCTX_INPROC_SERVER,
+                     IID_IDropTargetHelper, (LPVOID*)&mDropTargetHelper);
+  }
+
+  return mDropTargetHelper;
+}
--- a/widget/windows/nsNativeDragTarget.h
+++ b/widget/windows/nsNativeDragTarget.h
@@ -114,16 +114,20 @@ protected:
   HWND             mHWnd;
   DWORD            mEffectsAllowed;
   DWORD            mEffectsPreferred;
   bool             mTookOwnRef;
 
   // Gecko Stuff
   nsIWidget      * mWindow;
   nsIDragService * mDragService;
+  // Drag target helper 
+  IDropTargetHelper * GetDropTargetHelper();
 
+
+private:
   // Drag target helper 
   IDropTargetHelper * mDropTargetHelper;
 };
 
 #endif // _nsNativeDragTarget_h_