mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-11 12:25:53 +00:00
Backed out 2 changesets (bug 1377060) for build bustage a=backout
Backed out changeset c8f818803df7 (bug 1377060) Backed out changeset bf11ec80b0fb (bug 1377060) MozReview-Commit-ID: Hp1PtpWYOWV
This commit is contained in:
parent
6d0266b61b
commit
f8eb8f400a
@ -6,10 +6,7 @@
|
||||
|
||||
#include "PaintThread.h"
|
||||
|
||||
#include "base/task.h"
|
||||
#include "mozilla/layers/CompositorBridgeChild.h"
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/SyncRunnable.h"
|
||||
|
||||
namespace mozilla {
|
||||
@ -18,8 +15,6 @@ namespace layers {
|
||||
using namespace gfx;
|
||||
|
||||
StaticAutoPtr<PaintThread> PaintThread::sSingleton;
|
||||
StaticRefPtr<nsIThread> PaintThread::sThread;
|
||||
PlatformThreadId PaintThread::sThreadId;
|
||||
|
||||
void
|
||||
PaintThread::Release()
|
||||
@ -35,25 +30,24 @@ void
|
||||
PaintThread::InitOnPaintThread()
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
sThreadId = PlatformThread::CurrentId();
|
||||
mThreadId = PlatformThread::CurrentId();
|
||||
}
|
||||
|
||||
bool
|
||||
PaintThread::Init()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
nsresult rv = NS_NewNamedThread("PaintThread", getter_AddRefs(mThread));
|
||||
|
||||
RefPtr<nsIThread> thread;
|
||||
nsresult rv = NS_NewNamedThread("PaintThread", getter_AddRefs(thread));
|
||||
if (NS_FAILED(rv)) {
|
||||
return false;
|
||||
}
|
||||
sThread = thread;
|
||||
|
||||
nsCOMPtr<nsIRunnable> paintInitTask =
|
||||
NewRunnableMethod("PaintThread::InitOnPaintThread",
|
||||
this, &PaintThread::InitOnPaintThread);
|
||||
SyncRunnable::DispatchToThread(sThread, paintInitTask);
|
||||
|
||||
SyncRunnable::DispatchToThread(PaintThread::sSingleton->mThread, paintInitTask);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -75,83 +69,49 @@ PaintThread::Get()
|
||||
return PaintThread::sSingleton.get();
|
||||
}
|
||||
|
||||
void
|
||||
DestroyPaintThread(UniquePtr<PaintThread>&& pt)
|
||||
{
|
||||
MOZ_ASSERT(PaintThread::IsOnPaintThread());
|
||||
pt->ShutdownOnPaintThread();
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
PaintThread::Shutdown()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
UniquePtr<PaintThread> pt(sSingleton.forget());
|
||||
if (!pt) {
|
||||
if (!PaintThread::sSingleton) {
|
||||
return;
|
||||
}
|
||||
|
||||
sThread->Dispatch(NewRunnableFunction(DestroyPaintThread, Move(pt)));
|
||||
sThread->Shutdown();
|
||||
sThread = nullptr;
|
||||
PaintThread::sSingleton->ShutdownImpl();
|
||||
PaintThread::sSingleton = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
PaintThread::ShutdownOnPaintThread()
|
||||
PaintThread::ShutdownImpl()
|
||||
{
|
||||
MOZ_ASSERT(IsOnPaintThread());
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
PaintThread::sSingleton->mThread->AsyncShutdown();
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
bool
|
||||
PaintThread::IsOnPaintThread()
|
||||
{
|
||||
return sThreadId == PlatformThread::CurrentId();
|
||||
}
|
||||
|
||||
void
|
||||
PaintThread::PaintContentsAsync(CompositorBridgeChild* aBridge,
|
||||
gfx::DrawTargetCapture* aCapture,
|
||||
gfx::DrawTarget* aTarget)
|
||||
{
|
||||
MOZ_ASSERT(IsOnPaintThread());
|
||||
|
||||
// Draw all the things into the actual dest target.
|
||||
aTarget->DrawCapturedDT(aCapture, Matrix());
|
||||
|
||||
if (aBridge) {
|
||||
aBridge->NotifyFinishedAsyncPaint();
|
||||
}
|
||||
MOZ_ASSERT(mThread);
|
||||
return PlatformThread::CurrentId() == mThreadId;
|
||||
}
|
||||
|
||||
void
|
||||
PaintThread::PaintContents(DrawTargetCapture* aCapture,
|
||||
DrawTarget* aTarget)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
if (!IsOnPaintThread()) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
nsCOMPtr<nsIRunnable> paintTask =
|
||||
NewRunnableMethod<DrawTargetCapture*, DrawTarget*>("PaintThread::PaintContents",
|
||||
this,
|
||||
&PaintThread::PaintContents,
|
||||
aCapture, aTarget);
|
||||
|
||||
// If painting asynchronously, we need to acquire the compositor bridge which
|
||||
// owns the underlying MessageChannel. Otherwise we leave it null and use
|
||||
// synchronous dispatch.
|
||||
RefPtr<CompositorBridgeChild> cbc;
|
||||
if (!gfxPrefs::LayersOMTPForceSync()) {
|
||||
cbc = CompositorBridgeChild::Get();
|
||||
cbc->NotifyBeginAsyncPaint();
|
||||
SyncRunnable::DispatchToThread(mThread, paintTask);
|
||||
return;
|
||||
}
|
||||
RefPtr<DrawTargetCapture> capture(aCapture);
|
||||
RefPtr<DrawTarget> target(aTarget);
|
||||
|
||||
RefPtr<Runnable> task = NS_NewRunnableFunction("PaintThread::PaintContents",
|
||||
[=, this]() -> void
|
||||
{
|
||||
PaintContentsAsync(cbc, capture, target);
|
||||
});
|
||||
|
||||
if (cbc) {
|
||||
sThread->Dispatch(task.forget());
|
||||
} else {
|
||||
SyncRunnable::DispatchToThread(sThread, task);
|
||||
}
|
||||
// Draw all the things into the actual dest target.
|
||||
aTarget->DrawCapturedDT(aCapture, Matrix());
|
||||
}
|
||||
|
||||
} // namespace layers
|
||||
|
@ -9,7 +9,6 @@
|
||||
|
||||
#include "base/platform_thread.h"
|
||||
#include "mozilla/StaticPtr.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
@ -20,19 +19,14 @@ class DrawTargetCapture;
|
||||
|
||||
namespace layers {
|
||||
|
||||
class CompositorBridgeChild;
|
||||
|
||||
class PaintThread final
|
||||
{
|
||||
friend void DestroyPaintThread(UniquePtr<PaintThread>&& aPaintThread);
|
||||
|
||||
public:
|
||||
static void Start();
|
||||
static void Shutdown();
|
||||
static PaintThread* Get();
|
||||
void PaintContents(gfx::DrawTargetCapture* aCapture,
|
||||
gfx::DrawTarget* aTarget);
|
||||
|
||||
// Sync Runnables need threads to be ref counted,
|
||||
// But this thread lives through the whole process.
|
||||
// We're only temporarily using sync runnables so
|
||||
@ -40,23 +34,18 @@ public:
|
||||
void Release();
|
||||
void AddRef();
|
||||
|
||||
// Helper for asserts.
|
||||
static bool IsOnPaintThread();
|
||||
|
||||
private:
|
||||
bool IsOnPaintThread();
|
||||
bool Init();
|
||||
void ShutdownOnPaintThread();
|
||||
void ShutdownImpl();
|
||||
void InitOnPaintThread();
|
||||
void PaintContentsAsync(CompositorBridgeChild* aBridge,
|
||||
gfx::DrawTargetCapture* aCapture,
|
||||
gfx::DrawTarget* aTarget);
|
||||
|
||||
static StaticAutoPtr<PaintThread> sSingleton;
|
||||
static StaticRefPtr<nsIThread> sThread;
|
||||
static PlatformThreadId sThreadId;
|
||||
RefPtr<nsIThread> mThread;
|
||||
PlatformThreadId mThreadId;
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
#endif
|
@ -226,9 +226,6 @@ ClientLayerManager::CreateReadbackLayer()
|
||||
bool
|
||||
ClientLayerManager::BeginTransactionWithTarget(gfxContext* aTarget)
|
||||
{
|
||||
// Wait for any previous async paints to complete before starting to paint again.
|
||||
GetCompositorBridgeChild()->FlushAsyncPaints();
|
||||
|
||||
MOZ_ASSERT(mForwarder, "ClientLayerManager::BeginTransaction without forwarder");
|
||||
if (!mForwarder->IPCOpen()) {
|
||||
gfxCriticalNote << "ClientLayerManager::BeginTransaction with IPC channel down. GPU process may have died.";
|
||||
|
@ -19,7 +19,6 @@
|
||||
#include "mozilla/layers/IAPZCTreeManager.h"
|
||||
#include "mozilla/layers/APZCTreeManagerChild.h"
|
||||
#include "mozilla/layers/LayerTransactionChild.h"
|
||||
#include "mozilla/layers/PaintThread.h"
|
||||
#include "mozilla/layers/PLayerTransactionChild.h"
|
||||
#include "mozilla/layers/PTextureChild.h"
|
||||
#include "mozilla/layers/TextureClient.h"// for TextureClient
|
||||
@ -90,9 +89,6 @@ CompositorBridgeChild::CompositorBridgeChild(CompositorManagerChild *aManager)
|
||||
, mMessageLoop(MessageLoop::current())
|
||||
, mProcessToken(0)
|
||||
, mSectionAllocator(nullptr)
|
||||
, mPaintLock("CompositorBridgeChild.mPaintLock")
|
||||
, mOutstandingAsyncPaints(0)
|
||||
, mIsWaitingForPaint(false)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
}
|
||||
@ -546,20 +542,8 @@ CompositorBridgeChild::ActorDestroy(ActorDestroyReason aWhy)
|
||||
gfxCriticalNote << "Receive IPC close with reason=AbnormalShutdown";
|
||||
}
|
||||
|
||||
{
|
||||
// We take the lock to update these fields, since they are read from the
|
||||
// paint thread. We don't need the lock to init them, since that happens
|
||||
// on the main thread before the paint thread can ever grab a reference
|
||||
// to the CompositorBridge object.
|
||||
//
|
||||
// Note that it is useful to take this lock for one other reason: It also
|
||||
// tells us whether GetIPCChannel is safe to call. If we access the IPC
|
||||
// channel within this lock, when mCanSend is true, then we know it has not
|
||||
// been zapped by IPDL.
|
||||
MonitorAutoLock lock(mPaintLock);
|
||||
mCanSend = false;
|
||||
mActorDestroyed = true;
|
||||
}
|
||||
mCanSend = false;
|
||||
mActorDestroyed = true;
|
||||
|
||||
if (mProcessToken && XRE_IsParentProcess()) {
|
||||
GPUProcessManager::Get()->NotifyRemoteActorDestroyed(mProcessToken);
|
||||
@ -1130,86 +1114,6 @@ CompositorBridgeChild::GetNextPipelineId()
|
||||
return wr::AsPipelineId(GetNextResourceId());
|
||||
}
|
||||
|
||||
void
|
||||
CompositorBridgeChild::NotifyBeginAsyncPaint()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
MonitorAutoLock lock(mPaintLock);
|
||||
|
||||
// We must not be waiting for paints to complete yet. This would imply we
|
||||
// started a new paint without waiting for a previous one, which could lead to
|
||||
// incorrect rendering or IPDL deadlocks.
|
||||
MOZ_ASSERT(!mIsWaitingForPaint);
|
||||
|
||||
mOutstandingAsyncPaints++;
|
||||
}
|
||||
|
||||
void
|
||||
CompositorBridgeChild::NotifyFinishedAsyncPaint()
|
||||
{
|
||||
MOZ_ASSERT(PaintThread::IsOnPaintThread());
|
||||
|
||||
MonitorAutoLock lock(mPaintLock);
|
||||
|
||||
mOutstandingAsyncPaints--;
|
||||
|
||||
// It's possible that we painted so fast that the main thread never reached
|
||||
// the code that starts delaying messages. If so, mIsWaitingForPaint will be
|
||||
// false, and we can safely return.
|
||||
if (mIsWaitingForPaint && mOutstandingAsyncPaints == 0) {
|
||||
ResumeIPCAfterAsyncPaint();
|
||||
|
||||
// Notify the main thread in case it's blocking. We do this unconditionally
|
||||
// to avoid deadlocking.
|
||||
lock.Notify();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CompositorBridgeChild::PostponeMessagesIfAsyncPainting()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
MonitorAutoLock lock(mPaintLock);
|
||||
|
||||
MOZ_ASSERT(!mIsWaitingForPaint);
|
||||
|
||||
if (mOutstandingAsyncPaints > 0) {
|
||||
mIsWaitingForPaint = true;
|
||||
GetIPCChannel()->BeginPostponingSends();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CompositorBridgeChild::ResumeIPCAfterAsyncPaint()
|
||||
{
|
||||
// Note: the caller is responsible for holding the lock.
|
||||
mPaintLock.AssertCurrentThreadOwns();
|
||||
MOZ_ASSERT(PaintThread::IsOnPaintThread());
|
||||
MOZ_ASSERT(mOutstandingAsyncPaints == 0);
|
||||
MOZ_ASSERT(mIsWaitingForPaint);
|
||||
|
||||
mIsWaitingForPaint = false;
|
||||
|
||||
// It's also possible that the channel has shut down already.
|
||||
if (!mCanSend || mActorDestroyed) {
|
||||
return;
|
||||
}
|
||||
|
||||
GetIPCChannel()->StopPostponingSends();
|
||||
}
|
||||
|
||||
void
|
||||
CompositorBridgeChild::FlushAsyncPaints()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
MonitorAutoLock lock(mPaintLock);
|
||||
while (mIsWaitingForPaint) {
|
||||
lock.Wait();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
||||
|
@ -10,7 +10,6 @@
|
||||
#include "base/basictypes.h" // for DISALLOW_EVIL_CONSTRUCTORS
|
||||
#include "mozilla/Assertions.h" // for MOZ_ASSERT_HELPER2
|
||||
#include "mozilla/Attributes.h" // for override
|
||||
#include "mozilla/Monitor.h"
|
||||
#include "mozilla/ipc/ProtocolUtils.h"
|
||||
#include "mozilla/layers/PCompositorBridgeChild.h"
|
||||
#include "mozilla/layers/TextureForwarder.h" // for TextureForwarder
|
||||
@ -221,33 +220,10 @@ public:
|
||||
|
||||
wr::PipelineId GetNextPipelineId();
|
||||
|
||||
// Must only be called from the main thread. Notifies the CompositorBridge
|
||||
// that the paint thread is going to begin painting asynchronously.
|
||||
void NotifyBeginAsyncPaint();
|
||||
|
||||
// Must only be called from the paint thread. Notifies the CompositorBridge
|
||||
// that the paint thread has finished an asynchronous paint request.
|
||||
void NotifyFinishedAsyncPaint();
|
||||
|
||||
// Must only be called from the main thread. Notifies the CompoistorBridge
|
||||
// that a transaction is about to be sent, and if the paint thread is
|
||||
// currently painting, to begin delaying IPC messages.
|
||||
void PostponeMessagesIfAsyncPainting();
|
||||
|
||||
// Must only be called from the main thread. Ensures that any paints from
|
||||
// previous frames have been flushed. The main thread blocks until the
|
||||
// operation completes.
|
||||
void FlushAsyncPaints();
|
||||
|
||||
private:
|
||||
// Private destructor, to discourage deletion outside of Release():
|
||||
virtual ~CompositorBridgeChild();
|
||||
|
||||
// Must only be called from the paint thread. If the main thread is delaying
|
||||
// IPC messages, this forwards all such delayed IPC messages to the I/O thread
|
||||
// and resumes IPC.
|
||||
void ResumeIPCAfterAsyncPaint();
|
||||
|
||||
void AfterDestroy();
|
||||
|
||||
virtual PLayerTransactionChild*
|
||||
@ -352,20 +328,6 @@ private:
|
||||
uint64_t mProcessToken;
|
||||
|
||||
FixedSizeSmallShmemSectionAllocator* mSectionAllocator;
|
||||
|
||||
// Off-Main-Thread Painting state. This covers access to the OMTP-related
|
||||
// state below.
|
||||
Monitor mPaintLock;
|
||||
|
||||
// Contains the number of outstanding asynchronous paints tied to a
|
||||
// PLayerTransaction on this bridge. This is R/W on both the main and paint
|
||||
// threads, and must be accessed within the paint lock.
|
||||
size_t mOutstandingAsyncPaints;
|
||||
|
||||
// True if this CompositorBridge is currently delaying its messages until the
|
||||
// paint thread completes. This is R/W on both the main and paint threads, and
|
||||
// must be accessed within the paint lock.
|
||||
bool mIsWaitingForPaint;
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
|
@ -764,10 +764,6 @@ ShadowLayerForwarder::EndTransaction(const nsIntRegion& aRegionToClear,
|
||||
}
|
||||
}
|
||||
|
||||
// We delay at the last possible minute, to give the paint thread a chance to
|
||||
// finish. If it does we don't have to delay messages at all.
|
||||
GetCompositorBridgeChild()->PostponeMessagesIfAsyncPainting();
|
||||
|
||||
MOZ_LAYERS_LOG(("[LayersForwarder] sending transaction..."));
|
||||
RenderTraceScope rendertrace3("Forward Transaction", "000093");
|
||||
if (!mShadowManager->SendUpdate(info)) {
|
||||
|
@ -585,7 +585,6 @@ private:
|
||||
DECL_GFX_PREF(Once, "layers.mlgpu.enable-container-resizing", AdvancedLayersEnableContainerResizing, bool, true);
|
||||
DECL_GFX_PREF(Once, "layers.offmainthreadcomposition.force-disabled", LayersOffMainThreadCompositionForceDisabled, bool, false);
|
||||
DECL_GFX_PREF(Live, "layers.offmainthreadcomposition.frame-rate", LayersCompositionFrameRate, int32_t,-1);
|
||||
DECL_GFX_PREF(Live, "layers.omtp.force-sync", LayersOMTPForceSync, bool, true);
|
||||
DECL_GFX_PREF(Live, "layers.orientation.sync.timeout", OrientationSyncMillis, uint32_t, (uint32_t)0);
|
||||
DECL_GFX_PREF(Once, "layers.prefer-opengl", LayersPreferOpenGL, bool, false);
|
||||
DECL_GFX_PREF(Live, "layers.progressive-paint", ProgressivePaint, bool, false);
|
||||
|
@ -67,13 +67,6 @@ public:
|
||||
|
||||
T& operator*() const { return *get(); }
|
||||
|
||||
T* forget()
|
||||
{
|
||||
T* temp = mRawPtr;
|
||||
mRawPtr = nullptr;
|
||||
return temp;
|
||||
}
|
||||
|
||||
private:
|
||||
// Disallow copy constructor, but only in debug mode. We only define
|
||||
// a default constructor in debug mode (see above); if we declared
|
||||
|
Loading…
Reference in New Issue
Block a user