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:
Wes Kocher 2017-07-03 11:44:58 -07:00
parent 6d0266b61b
commit f8eb8f400a
8 changed files with 32 additions and 232 deletions

View File

@ -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

View File

@ -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

View File

@ -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.";

View File

@ -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

View File

@ -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

View File

@ -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)) {

View File

@ -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);

View File

@ -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