Bug 595277 - Part 4: Delay Direct3D 9 initialization when possible. r=roc a=blocking-final

This commit is contained in:
Bas Schouten 2010-12-07 03:06:31 +01:00
parent 52b7708d12
commit 903b02d6b8
4 changed files with 85 additions and 2 deletions

View File

@ -69,6 +69,14 @@ HINSTANCE nsToolkit::mDllInstance = 0;
PRBool nsToolkit::mIsWinXP = PR_FALSE;
static PRBool dummy = nsToolkit::InitVersionInfo();
static const unsigned long kD3DUsageDelay = 5000;
static void
StartAllowingD3D9(nsITimer *aTimer, void *aClosure)
{
nsWindow::StartAllowingD3D9(true);
}
#if !defined(MOZ_STATIC_COMPONENT_LIBS) && !defined(MOZ_ENABLE_LIBXUL)
//
// Dll entry point. Keep the dll instance
@ -239,6 +247,14 @@ nsToolkit::Shutdown()
::UnregisterClassW(L"nsToolkitClass", nsToolkit::mDllInstance);
}
void
nsToolkit::StartAllowingD3D9()
{
nsIToolkit *toolkit;
NS_GetCurrentToolkit(&toolkit);
static_cast<nsToolkit*>(toolkit)->mD3D9Timer->Cancel();
nsWindow::StartAllowingD3D9(false);
}
//-------------------------------------------------------------------------
//
@ -319,6 +335,12 @@ NS_METHOD nsToolkit::Init(PRThread *aThread)
CreateUIThread();
}
mD3D9Timer = do_CreateInstance("@mozilla.org/timer;1");
mD3D9Timer->InitWithFuncCallback(::StartAllowingD3D9,
NULL,
kD3DUsageDelay,
nsITimer::TYPE_ONE_SHOT);
nsWidgetAtoms::RegisterAtoms();
return NS_OK;

View File

@ -100,6 +100,7 @@ protected:
HWND mDispatchWnd;
// Thread Id of the "main" Gui thread.
PRThread *mGuiThread;
nsCOMPtr<nsITimer> mD3D9Timer;
public:
static HINSTANCE mDllInstance;
@ -109,6 +110,7 @@ public:
static PRBool InitVersionInfo();
static void Startup(HINSTANCE hModule);
static void Shutdown();
static void StartAllowingD3D9();
static MouseTrailer *gMouseTrailer;
};

View File

@ -159,6 +159,8 @@
#include "mozilla/Services.h"
#include "nsNativeThemeWin.h"
#include "nsWindowsDllInterceptor.h"
#include "nsIWindowMediator.h"
#include "nsIServiceManager.h"
#if defined(WINCE)
#include "nsWindowCE.h"
@ -296,6 +298,8 @@ PRBool nsWindow::sDefaultTrackPointHack = PR_FALSE;
// Default value for general window class (used when the pref is the empty string).
const char* nsWindow::sDefaultMainWindowClass = kClassNameGeneral;
// If we're using D3D9, this will not be allowed during initial 5 seconds.
bool nsWindow::sAllowD3D9 = false;
#ifdef ACCESSIBILITY
BOOL nsWindow::sIsAccessibilityOn = FALSE;
@ -3232,7 +3236,12 @@ nsWindow::GetLayerManager(LayerManagerPersistence aPersistence, bool* aAllowReta
}
#endif
if (!mLayerManager) {
if (!mLayerManager ||
(!sAllowD3D9 && aPersistence == LAYER_MANAGER_PERSISTENT &&
mLayerManager->GetBackendType() ==
mozilla::layers::LayerManager::LAYERS_BASIC)) {
// If D3D9 is not currently allowed but the permanent manager is required,
// -and- we're currently using basic layers, run through this check.
nsCOMPtr<nsIPrefBranch2> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
PRBool accelerateByDefault = PR_TRUE;
@ -3271,6 +3280,12 @@ nsWindow::GetLayerManager(LayerManagerPersistence aPersistence, bool* aAllowReta
mUseAcceleratedRendering = PR_TRUE;
if (mUseAcceleratedRendering) {
if (aPersistence == LAYER_MANAGER_PERSISTENT && !sAllowD3D9) {
// This will clear out our existing layer manager if we have one since
// if we hit this with a LayerManager we're always using BasicLayers.
nsToolkit::StartAllowingD3D9();
}
#ifdef MOZ_ENABLE_D3D10_LAYER
if (!preferD3D9) {
nsRefPtr<mozilla::layers::LayerManagerD3D10> layerManager =
@ -3281,7 +3296,7 @@ nsWindow::GetLayerManager(LayerManagerPersistence aPersistence, bool* aAllowReta
}
#endif
#ifdef MOZ_ENABLE_D3D9_LAYER
if (!preferOpenGL && !mLayerManager) {
if (!preferOpenGL && !mLayerManager && sAllowD3D9) {
nsRefPtr<mozilla::layers::LayerManagerD3D9> layerManager =
new mozilla::layers::LayerManagerD3D9(this);
if (layerManager->Initialize()) {
@ -7523,6 +7538,37 @@ PRBool nsWindow::AutoErase(HDC dc)
return PR_FALSE;
}
void
nsWindow::AllowD3D9Callback(nsWindow *aWindow)
{
if (aWindow->mLayerManager) {
aWindow->mLayerManager->Destroy();
aWindow->mLayerManager = NULL;
}
}
void
nsWindow::AllowD3D9WithReinitializeCallback(nsWindow *aWindow)
{
if (aWindow->mLayerManager) {
aWindow->mLayerManager->Destroy();
aWindow->mLayerManager = NULL;
(void) aWindow->GetLayerManager();
}
}
void
nsWindow::StartAllowingD3D9(bool aReinitialize)
{
sAllowD3D9 = true;
if (aReinitialize) {
EnumAllWindows(AllowD3D9WithReinitializeCallback);
} else {
EnumAllWindows(AllowD3D9Callback);
}
}
/**************************************************************
**************************************************************
**

View File

@ -59,6 +59,7 @@
#include "gfxWindowsSurface.h"
#include "nsWindowDbg.h"
#include "cairo.h"
#include "nsITimer.h"
#ifdef CAIRO_HAS_D2D_SURFACE
#include "gfxD2DSurface.h"
#endif
@ -259,6 +260,15 @@ public:
// needed in nsIMM32Handler.cpp
PRBool PluginHasFocus() { return mIMEContext.mStatus == nsIWidget::IME_STATUS_PLUGIN; }
PRBool IsTopLevelWidget() { return mIsTopWidgetWindow; }
/**
* Start allowing Direct3D9 to be used by widgets when GetLayerManager is
* called.
*
* @param aReinitialize Call GetLayerManager on widgets to ensure D3D9 is
* initialized, this is usually called when this function
* is triggered by timeout and not user/web interaction.
*/
static void StartAllowingD3D9(bool aReinitialize);
#if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_WIN7
PRBool HasTaskbarIconBeenCreated() { return mHasTaskbarIconBeenCreated; }
@ -297,6 +307,8 @@ protected:
static BOOL CALLBACK ClearResourcesCallback(HWND aChild, LPARAM aParam);
static BOOL CALLBACK EnumAllChildWindProc(HWND aWnd, LPARAM aParam);
static BOOL CALLBACK EnumAllThreadWindowProc(HWND aWnd, LPARAM aParam);
static void AllowD3D9Callback(nsWindow *aWindow);
static void AllowD3D9WithReinitializeCallback(nsWindow *aWindow);
/**
* Window utilities
@ -504,6 +516,7 @@ protected:
static int sTrimOnMinimize;
static PRBool sDefaultTrackPointHack;
static const char* sDefaultMainWindowClass;
static bool sAllowD3D9;
#ifdef MOZ_IPC
static PRUint32 sOOPPPluginFocusEvent;
#endif