mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 763234 - Use only one compositor thread with OMTC. r=cjones
This commit is contained in:
parent
03bce61cad
commit
049d5a6366
@ -23,8 +23,49 @@ using base::Thread;
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
CompositorParent::CompositorParent(nsIWidget* aWidget, MessageLoop* aMsgLoop,
|
||||
PlatformThreadId aThreadID, bool aRenderToEGLSurface,
|
||||
static Thread* sCompositorThread = nsnull;
|
||||
|
||||
void CompositorParent::StartUp()
|
||||
{
|
||||
CreateThread();
|
||||
}
|
||||
|
||||
void CompositorParent::ShutDown()
|
||||
{
|
||||
DestroyThread();
|
||||
}
|
||||
|
||||
bool CompositorParent::CreateThread()
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Should be on the main Thread!");
|
||||
if (sCompositorThread) {
|
||||
return true;
|
||||
}
|
||||
sCompositorThread = new Thread("Compositor");
|
||||
if (!sCompositorThread->Start()) {
|
||||
delete sCompositorThread;
|
||||
sCompositorThread = nsnull;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void CompositorParent::DestroyThread()
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Should be on the main Thread!");
|
||||
if (sCompositorThread) {
|
||||
delete sCompositorThread;
|
||||
sCompositorThread = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
MessageLoop* CompositorParent::CompositorLoop()
|
||||
{
|
||||
return sCompositorThread ? sCompositorThread->message_loop() : nsnull;
|
||||
}
|
||||
|
||||
CompositorParent::CompositorParent(nsIWidget* aWidget,
|
||||
bool aRenderToEGLSurface,
|
||||
int aSurfaceWidth, int aSurfaceHeight)
|
||||
: mWidget(aWidget)
|
||||
, mCurrentCompositeTask(NULL)
|
||||
@ -33,26 +74,20 @@ CompositorParent::CompositorParent(nsIWidget* aWidget, MessageLoop* aMsgLoop,
|
||||
, mYScale(1.0)
|
||||
, mIsFirstPaint(false)
|
||||
, mLayersUpdated(false)
|
||||
, mCompositorLoop(aMsgLoop)
|
||||
, mThreadID(aThreadID)
|
||||
, mRenderToEGLSurface(aRenderToEGLSurface)
|
||||
, mEGLSurfaceSize(aSurfaceWidth, aSurfaceHeight)
|
||||
, mPauseCompositionMonitor("PauseCompositionMonitor")
|
||||
, mResumeCompositionMonitor("ResumeCompositionMonitor")
|
||||
{
|
||||
NS_ABORT_IF_FALSE(sCompositorThread != nsnull,
|
||||
"The compositor thread must be Initialized before instanciating a COmpositorParent.");
|
||||
MOZ_COUNT_CTOR(CompositorParent);
|
||||
}
|
||||
|
||||
MessageLoop*
|
||||
CompositorParent::CompositorLoop()
|
||||
{
|
||||
return mCompositorLoop;
|
||||
}
|
||||
|
||||
PlatformThreadId
|
||||
CompositorParent::CompositorThreadID()
|
||||
{
|
||||
return mThreadID;
|
||||
return sCompositorThread->thread_id();
|
||||
}
|
||||
|
||||
CompositorParent::~CompositorParent()
|
||||
|
@ -23,6 +23,10 @@
|
||||
|
||||
class nsIWidget;
|
||||
|
||||
namespace base {
|
||||
class Thread;
|
||||
}
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
@ -53,8 +57,8 @@ class CompositorParent : public PCompositorParent,
|
||||
{
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CompositorParent)
|
||||
public:
|
||||
CompositorParent(nsIWidget* aWidget, MessageLoop* aMsgLoop,
|
||||
PlatformThreadId aThreadID, bool aRenderToEGLSurface = false,
|
||||
CompositorParent(nsIWidget* aWidget,
|
||||
bool aRenderToEGLSurface = false,
|
||||
int aSurfaceWidth = -1, int aSurfaceHeight = -1);
|
||||
|
||||
virtual ~CompositorParent();
|
||||
@ -77,6 +81,23 @@ public:
|
||||
void SchedulePauseOnCompositorThread();
|
||||
void ScheduleResumeOnCompositorThread(int width, int height);
|
||||
|
||||
/**
|
||||
* Returns the compositor thread's message loop.
|
||||
*
|
||||
* This message loop is used by CompositorParent and ImageBridgeParent.
|
||||
*/
|
||||
static MessageLoop* CompositorLoop();
|
||||
|
||||
/**
|
||||
* Creates the compositor thread and the global compositor map.
|
||||
*/
|
||||
static void StartUp();
|
||||
|
||||
/**
|
||||
* Destroys the compositor thread and the global compositor map.
|
||||
*/
|
||||
static void ShutDown();
|
||||
|
||||
protected:
|
||||
virtual PLayersParent* AllocPLayers(const LayersBackend& aBackendType, int* aMaxTextureSize);
|
||||
virtual bool DeallocPLayers(PLayersParent* aLayers);
|
||||
@ -96,9 +117,28 @@ private:
|
||||
|
||||
void TransformShadowTree();
|
||||
|
||||
inline MessageLoop* CompositorLoop();
|
||||
inline PlatformThreadId CompositorThreadID();
|
||||
|
||||
/**
|
||||
* Creates the compositor thread.
|
||||
*
|
||||
* All compositors live on the same thread.
|
||||
* The thread is not lazily created on first access to avoid dealing with
|
||||
* thread safety. Therefore it's best to create and destroy the thread when
|
||||
* we know we areb't using it (So creating/destroying along with gfxPlatform
|
||||
* looks like a good place).
|
||||
*/
|
||||
static bool CreateThread();
|
||||
|
||||
/**
|
||||
* Destroys the compositor thread.
|
||||
*
|
||||
* It is safe to call this fucntion more than once, although the second call
|
||||
* will have no effect.
|
||||
* This function is not thread-safe.
|
||||
*/
|
||||
static void DestroyThread();
|
||||
|
||||
// Platform specific functions
|
||||
/**
|
||||
* Does a breadth-first search to find the first layer in the tree with a
|
||||
@ -143,8 +183,6 @@ private:
|
||||
// after a layers update has it set. It is cleared after that first composition.
|
||||
bool mLayersUpdated;
|
||||
|
||||
MessageLoop* mCompositorLoop;
|
||||
PlatformThreadId mThreadID;
|
||||
bool mRenderToEGLSurface;
|
||||
nsIntSize mEGLSurfaceSize;
|
||||
|
||||
|
@ -6,10 +6,16 @@
|
||||
#ifdef MOZ_LOGGING
|
||||
#define FORCE_PR_LOG /* Allow logging in the release build */
|
||||
#endif
|
||||
|
||||
#include "mozilla/layers/CompositorParent.h"
|
||||
|
||||
#include "prlog.h"
|
||||
#include "prenv.h"
|
||||
|
||||
#include "gfxPlatform.h"
|
||||
|
||||
#include "nsXULAppAPI.h"
|
||||
|
||||
#if defined(XP_WIN)
|
||||
#include "gfxWindowsPlatform.h"
|
||||
#include "gfxD2DSurface.h"
|
||||
@ -60,6 +66,7 @@
|
||||
#include "nsIGfxInfo.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::layers;
|
||||
|
||||
gfxPlatform *gPlatform = nsnull;
|
||||
static bool gEverInitialized = false;
|
||||
@ -243,6 +250,30 @@ gfxPlatform::Init()
|
||||
sCmapDataLog = PR_NewLogModule("cmapdata");;
|
||||
#endif
|
||||
|
||||
bool useOffMainThreadCompositing = false;
|
||||
#ifdef MOZ_X11
|
||||
// On X11 platforms only use OMTC if firefox was initalized with thread-safe
|
||||
// X11 (else it would crash).
|
||||
useOffMainThreadCompositing = (PR_GetEnv("MOZ_USE_OMTC") != NULL);
|
||||
#else
|
||||
useOffMainThreadCompositing = Preferences::GetBool(
|
||||
"layers.offmainthreadcomposition.enabled",
|
||||
false);
|
||||
// Until https://bugzilla.mozilla.org/show_bug.cgi?id=745148 lands,
|
||||
// we use either omtc or content processes, but not both. Prefer
|
||||
// OOP content to omtc. (Currently, this only affects b2g.)
|
||||
//
|
||||
// See https://bugzilla.mozilla.org/show_bug.cgi?id=761962 .
|
||||
if (!Preferences::GetBool("dom.ipc.tabs.disabled", true)) {
|
||||
// Disable omtc if OOP content isn't force-disabled.
|
||||
useOffMainThreadCompositing = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (useOffMainThreadCompositing && (XRE_GetProcessType() ==
|
||||
GeckoProcessType_Default)) {
|
||||
CompositorParent::StartUp();
|
||||
}
|
||||
|
||||
/* Initialize the GfxInfo service.
|
||||
* Note: we can't call functions on GfxInfo that depend
|
||||
@ -360,6 +391,8 @@ gfxPlatform::Shutdown()
|
||||
mozilla::gl::GLContextProviderEGL::Shutdown();
|
||||
#endif
|
||||
|
||||
CompositorParent::ShutDown();
|
||||
|
||||
delete gPlatform;
|
||||
gPlatform = nsnull;
|
||||
}
|
||||
|
@ -171,7 +171,7 @@ nsWindow::~nsWindow()
|
||||
top->mFocus = nsnull;
|
||||
ALOG("nsWindow %p destructor", (void*)this);
|
||||
#ifdef MOZ_JAVA_COMPOSITOR
|
||||
SetCompositor(NULL, NULL, NULL);
|
||||
SetCompositor(NULL, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -697,7 +697,7 @@ nsWindow::GetLayerManager(PLayersChild*, LayersBackend, LayerManagerPersistence,
|
||||
if (useCompositor) {
|
||||
CreateCompositor();
|
||||
if (mLayerManager) {
|
||||
SetCompositor(mCompositorParent, mCompositorChild, mCompositorThread);
|
||||
SetCompositor(mCompositorParent, mCompositorChild);
|
||||
return mLayerManager;
|
||||
}
|
||||
|
||||
@ -2279,17 +2279,14 @@ nsWindow::DrawWindowOverlay(LayerManager* aManager, nsIntRect aRect)
|
||||
|
||||
nsRefPtr<mozilla::layers::CompositorParent> nsWindow::sCompositorParent = 0;
|
||||
nsRefPtr<mozilla::layers::CompositorChild> nsWindow::sCompositorChild = 0;
|
||||
base::Thread * nsWindow::sCompositorThread = 0;
|
||||
bool nsWindow::sCompositorPaused = false;
|
||||
|
||||
void
|
||||
nsWindow::SetCompositor(mozilla::layers::CompositorParent* aCompositorParent,
|
||||
mozilla::layers::CompositorChild* aCompositorChild,
|
||||
::base::Thread* aCompositorThread)
|
||||
mozilla::layers::CompositorChild* aCompositorChild)
|
||||
{
|
||||
sCompositorParent = aCompositorParent;
|
||||
sCompositorChild = aCompositorChild;
|
||||
sCompositorThread = aCompositorThread;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -152,8 +152,7 @@ public:
|
||||
virtual void DrawWindowOverlay(LayerManager* aManager, nsIntRect aRect);
|
||||
|
||||
static void SetCompositor(mozilla::layers::CompositorParent* aCompositorParent,
|
||||
mozilla::layers::CompositorChild* aCompositorChild,
|
||||
::base::Thread* aCompositorThread);
|
||||
mozilla::layers::CompositorChild* aCompositorChild);
|
||||
static void ScheduleComposite();
|
||||
static void SchedulePauseComposition();
|
||||
static void ScheduleResumeComposition(int width, int height);
|
||||
@ -219,7 +218,6 @@ private:
|
||||
static nsRefPtr<mozilla::layers::CompositorParent> sCompositorParent;
|
||||
static nsRefPtr<mozilla::layers::CompositorChild> sCompositorChild;
|
||||
static bool sCompositorPaused;
|
||||
static base::Thread *sCompositorThread;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -133,13 +133,6 @@ nsWindow::nsWindow()
|
||||
NS_RUNTIMEABORT("Failed to create framebufferWatcherThread, aborting...");
|
||||
}
|
||||
|
||||
sUsingOMTC = UseOffMainThreadCompositing();
|
||||
|
||||
if (sUsingOMTC) {
|
||||
sOMTCSurface = new gfxImageSurface(gfxIntSize(1, 1),
|
||||
gfxASurface::ImageFormatRGB24);
|
||||
}
|
||||
|
||||
// We (apparently) don't have a way to tell if allocating the
|
||||
// fbs succeeded or failed.
|
||||
gNativeWindow = new android::FramebufferNativeWindow();
|
||||
@ -172,6 +165,20 @@ nsWindow::nsWindow()
|
||||
sScreenInitialized = true;
|
||||
|
||||
nsAppShell::NotifyScreenInitialized();
|
||||
|
||||
// This is a hack to force initialization of the compositor
|
||||
// resources, if we're going to use omtc.
|
||||
//
|
||||
// NB: GetPlatform() will create the gfxPlatform, which wants
|
||||
// to know the color depth, which asks our native window.
|
||||
// This has to happen after other init has finished.
|
||||
gfxPlatform::GetPlatform();
|
||||
sUsingOMTC = UseOffMainThreadCompositing();
|
||||
|
||||
if (sUsingOMTC) {
|
||||
sOMTCSurface = new gfxImageSurface(gfxIntSize(1, 1),
|
||||
gfxASurface::ImageFormatRGB24);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -40,9 +40,6 @@ static bool debug_InSecureKeyboardInputMode = false;
|
||||
static PRInt32 gNumWidgets;
|
||||
#endif
|
||||
|
||||
static void InitOnlyOnce();
|
||||
static bool sUseOffMainThreadCompositing = false;
|
||||
|
||||
using namespace mozilla::layers;
|
||||
using namespace mozilla;
|
||||
using base::Thread;
|
||||
@ -84,7 +81,6 @@ nsBaseWidget::nsBaseWidget()
|
||||
, mEventCallback(nsnull)
|
||||
, mViewCallback(nsnull)
|
||||
, mContext(nsnull)
|
||||
, mCompositorThread(nsnull)
|
||||
, mCursor(eCursor_standard)
|
||||
, mWindowType(eWindowType_child)
|
||||
, mBorderStyle(eBorderStyle_none)
|
||||
@ -108,16 +104,13 @@ nsBaseWidget::nsBaseWidget()
|
||||
#ifdef DEBUG
|
||||
debug_RegisterPrefCallbacks();
|
||||
#endif
|
||||
InitOnlyOnce();
|
||||
}
|
||||
|
||||
|
||||
static void DeferredDestroyCompositor(CompositorParent* aCompositorParent,
|
||||
CompositorChild* aCompositorChild,
|
||||
Thread* aCompositorThread)
|
||||
CompositorChild* aCompositorChild)
|
||||
{
|
||||
aCompositorChild->Destroy();
|
||||
delete aCompositorThread;
|
||||
aCompositorParent->Release();
|
||||
aCompositorChild->Release();
|
||||
}
|
||||
@ -136,7 +129,7 @@ void nsBaseWidget::DestroyCompositor()
|
||||
// handle compositor desctruction.
|
||||
MessageLoop::current()->PostTask(FROM_HERE,
|
||||
NewRunnableFunction(DeferredDestroyCompositor, mCompositorParent,
|
||||
mCompositorChild, mCompositorThread));
|
||||
mCompositorChild));
|
||||
// The DestroyCompositor task we just added to the MessageLoop will handle
|
||||
// releasing mCompositorParent and mCompositorChild.
|
||||
mCompositorParent.forget();
|
||||
@ -869,52 +862,48 @@ nsBaseWidget::GetShouldAccelerate()
|
||||
|
||||
void nsBaseWidget::CreateCompositor()
|
||||
{
|
||||
mCompositorThread = new Thread("CompositorThread");
|
||||
if (mCompositorThread->Start()) {
|
||||
bool renderToEGLSurface = false;
|
||||
bool renderToEGLSurface = false;
|
||||
#ifdef MOZ_JAVA_COMPOSITOR
|
||||
renderToEGLSurface = true;
|
||||
renderToEGLSurface = true;
|
||||
#endif
|
||||
nsIntRect rect;
|
||||
GetBounds(rect);
|
||||
mCompositorParent =
|
||||
new CompositorParent(this, mCompositorThread->message_loop(), mCompositorThread->thread_id(),
|
||||
renderToEGLSurface, rect.width, rect.height);
|
||||
LayerManager* lm = CreateBasicLayerManager();
|
||||
MessageLoop *childMessageLoop = mCompositorThread->message_loop();
|
||||
mCompositorChild = new CompositorChild(lm);
|
||||
AsyncChannel *parentChannel = mCompositorParent->GetIPCChannel();
|
||||
AsyncChannel::Side childSide = mozilla::ipc::AsyncChannel::Child;
|
||||
mCompositorChild->Open(parentChannel, childMessageLoop, childSide);
|
||||
PRInt32 maxTextureSize;
|
||||
PLayersChild* shadowManager;
|
||||
if (mUseAcceleratedRendering) {
|
||||
shadowManager = mCompositorChild->SendPLayersConstructor(LayerManager::LAYERS_OPENGL, &maxTextureSize);
|
||||
} else {
|
||||
shadowManager = mCompositorChild->SendPLayersConstructor(LayerManager::LAYERS_BASIC, &maxTextureSize);
|
||||
}
|
||||
nsIntRect rect;
|
||||
GetBounds(rect);
|
||||
mCompositorParent =
|
||||
new CompositorParent(this, renderToEGLSurface, rect.width, rect.height);
|
||||
LayerManager* lm = CreateBasicLayerManager();
|
||||
MessageLoop *childMessageLoop = CompositorParent::CompositorLoop();
|
||||
mCompositorChild = new CompositorChild(lm);
|
||||
AsyncChannel *parentChannel = mCompositorParent->GetIPCChannel();
|
||||
AsyncChannel::Side childSide = mozilla::ipc::AsyncChannel::Child;
|
||||
mCompositorChild->Open(parentChannel, childMessageLoop, childSide);
|
||||
PRInt32 maxTextureSize;
|
||||
PLayersChild* shadowManager;
|
||||
if (mUseAcceleratedRendering) {
|
||||
shadowManager = mCompositorChild->SendPLayersConstructor(LayerManager::LAYERS_OPENGL, &maxTextureSize);
|
||||
} else {
|
||||
shadowManager = mCompositorChild->SendPLayersConstructor(LayerManager::LAYERS_BASIC, &maxTextureSize);
|
||||
}
|
||||
|
||||
if (shadowManager) {
|
||||
ShadowLayerForwarder* lf = lm->AsShadowForwarder();
|
||||
if (!lf) {
|
||||
delete lm;
|
||||
mCompositorChild = nsnull;
|
||||
return;
|
||||
}
|
||||
lf->SetShadowManager(shadowManager);
|
||||
if (mUseAcceleratedRendering)
|
||||
lf->SetParentBackendType(LayerManager::LAYERS_OPENGL);
|
||||
else
|
||||
lf->SetParentBackendType(LayerManager::LAYERS_BASIC);
|
||||
lf->SetMaxTextureSize(maxTextureSize);
|
||||
|
||||
mLayerManager = lm;
|
||||
} else {
|
||||
// We don't currently want to support not having a LayersChild
|
||||
NS_RUNTIMEABORT("failed to construct LayersChild");
|
||||
if (shadowManager) {
|
||||
ShadowLayerForwarder* lf = lm->AsShadowForwarder();
|
||||
if (!lf) {
|
||||
delete lm;
|
||||
mCompositorChild = nsnull;
|
||||
return;
|
||||
}
|
||||
lf->SetShadowManager(shadowManager);
|
||||
if (mUseAcceleratedRendering)
|
||||
lf->SetParentBackendType(LayerManager::LAYERS_OPENGL);
|
||||
else
|
||||
lf->SetParentBackendType(LayerManager::LAYERS_BASIC);
|
||||
lf->SetMaxTextureSize(maxTextureSize);
|
||||
|
||||
mLayerManager = lm;
|
||||
} else {
|
||||
// We don't currently want to support not having a LayersChild
|
||||
NS_RUNTIMEABORT("failed to construct LayersChild");
|
||||
delete lm;
|
||||
mCompositorChild = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
@ -922,7 +911,7 @@ bool nsBaseWidget::UseOffMainThreadCompositing()
|
||||
{
|
||||
bool isSmallPopup = ((mWindowType == eWindowType_popup) &&
|
||||
(mPopupType != ePopupTypePanel));
|
||||
return sUseOffMainThreadCompositing && !isSmallPopup;
|
||||
return CompositorParent::CompositorLoop() && !isSmallPopup;
|
||||
}
|
||||
|
||||
LayerManager* nsBaseWidget::GetLayerManager(PLayersChild* aShadowManager,
|
||||
@ -1336,34 +1325,6 @@ nsBaseWidget::GetGLFrameBufferFormat()
|
||||
return LOCAL_GL_NONE;
|
||||
}
|
||||
|
||||
static void InitOnlyOnce()
|
||||
{
|
||||
static bool once = true;
|
||||
if (!once) {
|
||||
return;
|
||||
}
|
||||
once = false;
|
||||
|
||||
#ifdef MOZ_X11
|
||||
// On X11 platforms only use OMTC if firefox was initalized with thread-safe
|
||||
// X11 (else it would crash).
|
||||
sUseOffMainThreadCompositing = (PR_GetEnv("MOZ_USE_OMTC") != NULL);
|
||||
#else
|
||||
sUseOffMainThreadCompositing = Preferences::GetBool(
|
||||
"layers.offmainthreadcomposition.enabled",
|
||||
false);
|
||||
// Until https://bugzilla.mozilla.org/show_bug.cgi?id=745148 lands,
|
||||
// we use either omtc or content processes, but not both. Prefer
|
||||
// OOP content to omtc. (Currently, this only affects b2g.)
|
||||
//
|
||||
// See https://bugzilla.mozilla.org/show_bug.cgi?id=761962 .
|
||||
if (!Preferences::GetBool("dom.ipc.tabs.disabled", true)) {
|
||||
// Disable omtc if OOP content isn't force-disabled.
|
||||
sUseOffMainThreadCompositing = false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
//////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
@ -296,7 +296,6 @@ protected:
|
||||
nsRefPtr<LayerManager> mBasicLayerManager;
|
||||
nsRefPtr<CompositorChild> mCompositorChild;
|
||||
nsRefPtr<CompositorParent> mCompositorParent;
|
||||
Thread* mCompositorThread;
|
||||
nscolor mBackground;
|
||||
nscolor mForeground;
|
||||
nsCursor mCursor;
|
||||
|
Loading…
Reference in New Issue
Block a user