2017-06-09 23:30:00 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
2017-10-28 02:10:06 +03:00
|
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
2017-06-09 23:30:00 +03:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
|
|
|
|
#include "PaintThread.h"
|
|
|
|
|
2017-07-06 01:19:47 +03:00
|
|
|
#include "base/task.h"
|
2017-07-06 01:19:52 +03:00
|
|
|
#include "gfxPrefs.h"
|
2017-10-30 21:48:16 +03:00
|
|
|
#include "GeckoProfiler.h"
|
2017-07-06 01:19:52 +03:00
|
|
|
#include "mozilla/layers/CompositorBridgeChild.h"
|
2017-08-11 07:41:31 +03:00
|
|
|
#include "mozilla/layers/ShadowLayers.h"
|
|
|
|
#include "mozilla/layers/SyncObject.h"
|
2017-06-22 18:36:14 +03:00
|
|
|
#include "mozilla/gfx/2D.h"
|
2017-07-06 01:19:52 +03:00
|
|
|
#include "mozilla/Preferences.h"
|
2017-06-20 23:35:39 +03:00
|
|
|
#include "mozilla/SyncRunnable.h"
|
|
|
|
|
2017-11-14 22:05:55 +03:00
|
|
|
// Uncomment the following line to dispatch sync runnables when
|
|
|
|
// painting so that rasterization happens synchronously from
|
|
|
|
// the perspective of the main thread
|
|
|
|
// #define OMTP_FORCE_SYNC
|
|
|
|
|
2017-06-09 23:30:00 +03:00
|
|
|
namespace mozilla {
|
|
|
|
namespace layers {
|
|
|
|
|
2017-06-20 23:35:39 +03:00
|
|
|
using namespace gfx;
|
|
|
|
|
2017-10-25 17:20:49 +03:00
|
|
|
bool
|
|
|
|
CapturedBufferState::Copy::CopyBuffer()
|
|
|
|
{
|
|
|
|
if (mSource->Lock(OpenMode::OPEN_READ_ONLY)) {
|
|
|
|
mDestination->UpdateDestinationFrom(*mSource, mBounds);
|
|
|
|
mSource->Unlock();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
CapturedBufferState::Unrotate::UnrotateBuffer()
|
|
|
|
{
|
|
|
|
return mBuffer->UnrotateBufferTo(mParameters);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
CapturedBufferState::PrepareBuffer()
|
|
|
|
{
|
2017-11-17 09:37:01 +03:00
|
|
|
return (!mBufferFinalize || mBufferFinalize->CopyBuffer()) &&
|
|
|
|
(!mBufferUnrotate || mBufferUnrotate->UnrotateBuffer()) &&
|
|
|
|
(!mBufferInitialize || mBufferInitialize->CopyBuffer());
|
2017-10-25 17:20:49 +03:00
|
|
|
}
|
|
|
|
|
2017-10-26 07:47:17 +03:00
|
|
|
void
|
|
|
|
CapturedBufferState::GetTextureClients(nsTArray<RefPtr<TextureClient>>& aTextureClients)
|
|
|
|
{
|
2017-11-17 09:37:01 +03:00
|
|
|
if (mBufferFinalize) {
|
|
|
|
if (TextureClient* source = mBufferFinalize->mSource->GetClient()) {
|
2017-10-26 07:47:17 +03:00
|
|
|
aTextureClients.AppendElement(source);
|
|
|
|
}
|
2017-11-17 09:37:01 +03:00
|
|
|
if (TextureClient* sourceOnWhite = mBufferFinalize->mSource->GetClientOnWhite()) {
|
2017-10-26 07:47:17 +03:00
|
|
|
aTextureClients.AppendElement(sourceOnWhite);
|
|
|
|
}
|
2017-11-17 09:37:01 +03:00
|
|
|
if (TextureClient* destination = mBufferFinalize->mDestination->GetClient()) {
|
2017-10-26 07:47:17 +03:00
|
|
|
aTextureClients.AppendElement(destination);
|
|
|
|
}
|
2017-11-17 09:37:01 +03:00
|
|
|
if (TextureClient* destinationOnWhite = mBufferFinalize->mDestination->GetClientOnWhite()) {
|
2017-10-26 07:47:17 +03:00
|
|
|
aTextureClients.AppendElement(destinationOnWhite);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mBufferUnrotate) {
|
|
|
|
if (TextureClient* client = mBufferUnrotate->mBuffer->GetClient()) {
|
|
|
|
aTextureClients.AppendElement(client);
|
|
|
|
}
|
|
|
|
if (TextureClient* clientOnWhite = mBufferUnrotate->mBuffer->GetClientOnWhite()) {
|
|
|
|
aTextureClients.AppendElement(clientOnWhite);
|
|
|
|
}
|
|
|
|
}
|
2017-11-17 09:37:01 +03:00
|
|
|
|
|
|
|
if (mBufferInitialize) {
|
|
|
|
if (TextureClient* source = mBufferInitialize->mSource->GetClient()) {
|
|
|
|
aTextureClients.AppendElement(source);
|
|
|
|
}
|
|
|
|
if (TextureClient* sourceOnWhite = mBufferInitialize->mSource->GetClientOnWhite()) {
|
|
|
|
aTextureClients.AppendElement(sourceOnWhite);
|
|
|
|
}
|
|
|
|
if (TextureClient* destination = mBufferInitialize->mDestination->GetClient()) {
|
|
|
|
aTextureClients.AppendElement(destination);
|
|
|
|
}
|
|
|
|
if (TextureClient* destinationOnWhite = mBufferInitialize->mDestination->GetClientOnWhite()) {
|
|
|
|
aTextureClients.AppendElement(destinationOnWhite);
|
|
|
|
}
|
|
|
|
}
|
2017-10-26 07:47:17 +03:00
|
|
|
}
|
|
|
|
|
2017-06-09 23:30:00 +03:00
|
|
|
StaticAutoPtr<PaintThread> PaintThread::sSingleton;
|
2017-07-06 01:19:47 +03:00
|
|
|
StaticRefPtr<nsIThread> PaintThread::sThread;
|
|
|
|
PlatformThreadId PaintThread::sThreadId;
|
2017-06-09 23:30:00 +03:00
|
|
|
|
2017-08-04 08:55:44 +03:00
|
|
|
// RAII make sure we clean up and restore our draw targets
|
|
|
|
// when we paint async.
|
2017-08-05 21:54:11 +03:00
|
|
|
struct MOZ_STACK_CLASS AutoCapturedPaintSetup
|
|
|
|
{
|
|
|
|
AutoCapturedPaintSetup(CapturedPaintState* aState, CompositorBridgeChild* aBridge)
|
|
|
|
: mState(aState)
|
2017-10-18 21:46:54 +03:00
|
|
|
, mTarget(aState->mTargetDual)
|
2017-08-05 21:54:11 +03:00
|
|
|
, mRestorePermitsSubpixelAA(mTarget->GetPermitSubpixelAA())
|
|
|
|
, mOldTransform(mTarget->GetTransform())
|
2017-08-04 08:55:44 +03:00
|
|
|
, mBridge(aBridge)
|
|
|
|
{
|
2017-08-05 21:54:11 +03:00
|
|
|
mTarget->SetTransform(aState->mCapture->GetTransform());
|
|
|
|
mTarget->SetPermitSubpixelAA(aState->mCapture->GetPermitSubpixelAA());
|
2017-08-04 08:55:44 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
~AutoCapturedPaintSetup()
|
|
|
|
{
|
|
|
|
mTarget->SetTransform(mOldTransform);
|
|
|
|
mTarget->SetPermitSubpixelAA(mRestorePermitsSubpixelAA);
|
2017-11-14 22:05:55 +03:00
|
|
|
mBridge->NotifyFinishedAsyncPaint(mState);
|
2017-08-04 08:55:44 +03:00
|
|
|
}
|
|
|
|
|
2017-08-05 21:54:11 +03:00
|
|
|
RefPtr<CapturedPaintState> mState;
|
2017-08-09 18:24:15 +03:00
|
|
|
RefPtr<DrawTarget> mTarget;
|
2017-08-04 08:55:44 +03:00
|
|
|
bool mRestorePermitsSubpixelAA;
|
|
|
|
Matrix mOldTransform;
|
|
|
|
RefPtr<CompositorBridgeChild> mBridge;
|
|
|
|
};
|
|
|
|
|
2017-10-30 21:49:58 +03:00
|
|
|
PaintThread::PaintThread()
|
|
|
|
: mInAsyncPaintGroup(false)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2017-06-20 23:35:39 +03:00
|
|
|
void
|
|
|
|
PaintThread::Release()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
PaintThread::AddRef()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2017-08-17 00:53:15 +03:00
|
|
|
/* static */ void
|
|
|
|
PaintThread::Start()
|
2017-06-20 23:35:39 +03:00
|
|
|
{
|
2017-08-17 00:53:15 +03:00
|
|
|
PaintThread::sSingleton = new PaintThread();
|
|
|
|
|
|
|
|
if (!PaintThread::sSingleton->Init()) {
|
|
|
|
gfxCriticalNote << "Unable to start paint thread";
|
|
|
|
PaintThread::sSingleton = nullptr;
|
|
|
|
}
|
2017-06-20 23:35:39 +03:00
|
|
|
}
|
|
|
|
|
2017-06-09 23:30:00 +03:00
|
|
|
bool
|
|
|
|
PaintThread::Init()
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
|
2017-07-06 01:19:47 +03:00
|
|
|
RefPtr<nsIThread> thread;
|
|
|
|
nsresult rv = NS_NewNamedThread("PaintThread", getter_AddRefs(thread));
|
2017-06-09 23:30:00 +03:00
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return false;
|
|
|
|
}
|
2017-07-06 01:19:47 +03:00
|
|
|
sThread = thread;
|
2017-06-09 23:30:00 +03:00
|
|
|
|
2017-06-20 23:35:39 +03:00
|
|
|
nsCOMPtr<nsIRunnable> paintInitTask =
|
2017-06-12 22:34:10 +03:00
|
|
|
NewRunnableMethod("PaintThread::InitOnPaintThread",
|
|
|
|
this, &PaintThread::InitOnPaintThread);
|
2017-07-06 01:19:47 +03:00
|
|
|
SyncRunnable::DispatchToThread(sThread, paintInitTask);
|
2017-06-09 23:30:00 +03:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-08-17 00:53:15 +03:00
|
|
|
void
|
|
|
|
PaintThread::InitOnPaintThread()
|
2017-06-09 23:30:00 +03:00
|
|
|
{
|
2017-08-17 00:53:15 +03:00
|
|
|
MOZ_ASSERT(!NS_IsMainThread());
|
|
|
|
sThreadId = PlatformThread::CurrentId();
|
2017-06-09 23:30:00 +03:00
|
|
|
}
|
|
|
|
|
2017-07-06 01:19:47 +03:00
|
|
|
void
|
|
|
|
DestroyPaintThread(UniquePtr<PaintThread>&& pt)
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(PaintThread::IsOnPaintThread());
|
|
|
|
pt->ShutdownOnPaintThread();
|
|
|
|
}
|
|
|
|
|
2017-06-09 23:30:00 +03:00
|
|
|
/* static */ void
|
|
|
|
PaintThread::Shutdown()
|
|
|
|
{
|
2017-07-06 01:19:47 +03:00
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
|
|
|
|
UniquePtr<PaintThread> pt(sSingleton.forget());
|
|
|
|
if (!pt) {
|
2017-06-09 23:30:00 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-07-06 01:19:47 +03:00
|
|
|
sThread->Dispatch(NewRunnableFunction(DestroyPaintThread, Move(pt)));
|
|
|
|
sThread->Shutdown();
|
|
|
|
sThread = nullptr;
|
2017-06-09 23:30:00 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2017-07-06 01:19:47 +03:00
|
|
|
PaintThread::ShutdownOnPaintThread()
|
2017-06-09 23:30:00 +03:00
|
|
|
{
|
2017-07-06 01:19:47 +03:00
|
|
|
MOZ_ASSERT(IsOnPaintThread());
|
2017-06-09 23:30:00 +03:00
|
|
|
}
|
|
|
|
|
2017-08-17 00:53:15 +03:00
|
|
|
/* static */ PaintThread*
|
|
|
|
PaintThread::Get()
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
return PaintThread::sSingleton.get();
|
|
|
|
}
|
|
|
|
|
2017-07-06 01:19:47 +03:00
|
|
|
/* static */ bool
|
2017-06-20 23:35:39 +03:00
|
|
|
PaintThread::IsOnPaintThread()
|
|
|
|
{
|
2017-07-06 01:19:47 +03:00
|
|
|
return sThreadId == PlatformThread::CurrentId();
|
2017-06-20 23:35:39 +03:00
|
|
|
}
|
|
|
|
|
2017-10-30 21:49:58 +03:00
|
|
|
void
|
|
|
|
PaintThread::BeginLayerTransaction()
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
|
|
|
|
MOZ_ASSERT(!mInAsyncPaintGroup);
|
2017-10-26 07:47:17 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
PaintThread::PrepareBuffer(CapturedBufferState* aState)
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
MOZ_ASSERT(aState);
|
|
|
|
|
|
|
|
// If painting asynchronously, we need to acquire the compositor bridge which
|
|
|
|
// owns the underlying MessageChannel. Otherwise we leave it null and use
|
|
|
|
// synchronous dispatch.
|
2017-11-14 22:05:55 +03:00
|
|
|
RefPtr<CompositorBridgeChild> cbc(CompositorBridgeChild::Get());
|
2017-10-26 07:47:17 +03:00
|
|
|
RefPtr<CapturedBufferState> state(aState);
|
|
|
|
|
2017-11-14 22:05:55 +03:00
|
|
|
cbc->NotifyBeginAsyncPrepareBuffer(state);
|
|
|
|
|
2017-10-26 07:47:17 +03:00
|
|
|
RefPtr<PaintThread> self = this;
|
|
|
|
RefPtr<Runnable> task = NS_NewRunnableFunction("PaintThread::PrepareBuffer",
|
|
|
|
[self, cbc, state]() -> void
|
|
|
|
{
|
|
|
|
self->AsyncPrepareBuffer(cbc,
|
|
|
|
state);
|
|
|
|
});
|
|
|
|
|
2017-11-14 22:05:55 +03:00
|
|
|
#ifndef OMTP_FORCE_SYNC
|
|
|
|
sThread->Dispatch(task.forget());
|
|
|
|
#else
|
|
|
|
SyncRunnable::DispatchToThread(sThread, task);
|
|
|
|
#endif
|
2017-10-26 07:47:17 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
PaintThread::AsyncPrepareBuffer(CompositorBridgeChild* aBridge,
|
|
|
|
CapturedBufferState* aState)
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(IsOnPaintThread());
|
|
|
|
MOZ_ASSERT(aState);
|
|
|
|
|
|
|
|
if (!mInAsyncPaintGroup) {
|
|
|
|
mInAsyncPaintGroup = true;
|
|
|
|
PROFILER_TRACING("Paint", "Rasterize", TRACING_INTERVAL_START);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!aState->PrepareBuffer()) {
|
|
|
|
gfxCriticalNote << "Failed to prepare buffers on the paint thread.";
|
|
|
|
}
|
|
|
|
|
2017-11-14 22:05:55 +03:00
|
|
|
aBridge->NotifyFinishedAsyncPrepareBuffer(aState);
|
2017-10-26 07:47:17 +03:00
|
|
|
}
|
|
|
|
|
2017-08-17 00:53:15 +03:00
|
|
|
void
|
|
|
|
PaintThread::PaintContents(CapturedPaintState* aState,
|
|
|
|
PrepDrawTargetForPaintingCallback aCallback)
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
MOZ_ASSERT(aState);
|
|
|
|
|
2017-11-14 22:05:55 +03:00
|
|
|
RefPtr<CompositorBridgeChild> cbc(CompositorBridgeChild::Get());
|
2017-08-17 00:53:15 +03:00
|
|
|
RefPtr<CapturedPaintState> state(aState);
|
|
|
|
|
2017-11-14 22:05:55 +03:00
|
|
|
cbc->NotifyBeginAsyncPaint(state);
|
|
|
|
|
2017-08-17 00:53:15 +03:00
|
|
|
RefPtr<PaintThread> self = this;
|
|
|
|
RefPtr<Runnable> task = NS_NewRunnableFunction("PaintThread::PaintContents",
|
2017-10-31 08:55:24 +03:00
|
|
|
[self, cbc, state, aCallback]() -> void
|
2017-08-17 00:53:15 +03:00
|
|
|
{
|
|
|
|
self->AsyncPaintContents(cbc,
|
|
|
|
state,
|
|
|
|
aCallback);
|
|
|
|
});
|
|
|
|
|
2017-11-14 22:05:55 +03:00
|
|
|
#ifndef OMTP_FORCE_SYNC
|
|
|
|
sThread->Dispatch(task.forget());
|
|
|
|
#else
|
|
|
|
SyncRunnable::DispatchToThread(sThread, task);
|
|
|
|
#endif
|
2017-08-17 00:53:15 +03:00
|
|
|
}
|
|
|
|
|
2017-07-03 21:20:33 +03:00
|
|
|
void
|
2017-08-17 00:02:13 +03:00
|
|
|
PaintThread::AsyncPaintContents(CompositorBridgeChild* aBridge,
|
2017-08-03 18:50:32 +03:00
|
|
|
CapturedPaintState* aState,
|
|
|
|
PrepDrawTargetForPaintingCallback aCallback)
|
2017-07-03 21:20:33 +03:00
|
|
|
{
|
2017-07-06 01:19:47 +03:00
|
|
|
MOZ_ASSERT(IsOnPaintThread());
|
2017-08-03 18:50:32 +03:00
|
|
|
MOZ_ASSERT(aState);
|
|
|
|
|
2017-10-30 21:49:58 +03:00
|
|
|
if (!mInAsyncPaintGroup) {
|
|
|
|
mInAsyncPaintGroup = true;
|
2017-10-30 21:48:16 +03:00
|
|
|
PROFILER_TRACING("Paint", "Rasterize", TRACING_INTERVAL_START);
|
2017-10-30 21:49:58 +03:00
|
|
|
}
|
|
|
|
|
2017-10-18 21:46:54 +03:00
|
|
|
DrawTarget* target = aState->mTargetDual;
|
2017-08-04 08:55:44 +03:00
|
|
|
DrawTargetCapture* capture = aState->mCapture;
|
2017-08-03 18:50:32 +03:00
|
|
|
|
2017-08-05 21:54:11 +03:00
|
|
|
AutoCapturedPaintSetup setup(aState, aBridge);
|
2017-08-03 18:50:32 +03:00
|
|
|
|
|
|
|
if (!aCallback(aState)) {
|
|
|
|
return;
|
|
|
|
}
|
2017-07-03 21:44:58 +03:00
|
|
|
|
|
|
|
// Draw all the things into the actual dest target.
|
2017-08-04 08:55:44 +03:00
|
|
|
target->DrawCapturedDT(capture, Matrix());
|
2017-08-09 18:24:15 +03:00
|
|
|
if (!mDrawTargetsToFlush.Contains(target)) {
|
|
|
|
mDrawTargetsToFlush.AppendElement(target);
|
|
|
|
}
|
2017-10-02 05:20:40 +03:00
|
|
|
|
|
|
|
if (gfxPrefs::LayersOMTPReleaseCaptureOnMainThread()) {
|
|
|
|
// This should ensure the capture drawtarget, which may hold on to UnscaledFont objects,
|
|
|
|
// gets destroyed on the main thread (See bug 1404742). This assumes (unflushed) target
|
|
|
|
// DrawTargets do not themselves hold on to UnscaledFonts.
|
|
|
|
NS_ReleaseOnMainThreadSystemGroup("CapturePaintState::DrawTargetCapture", aState->mCapture.forget());
|
|
|
|
}
|
2017-08-09 18:24:15 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2017-08-17 00:02:13 +03:00
|
|
|
PaintThread::EndLayer()
|
2017-08-09 18:24:15 +03:00
|
|
|
{
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
|
|
|
|
RefPtr<PaintThread> self = this;
|
2017-08-17 00:02:13 +03:00
|
|
|
RefPtr<Runnable> task = NS_NewRunnableFunction("PaintThread::AsyncEndLayer",
|
2017-08-15 00:27:03 +03:00
|
|
|
[self]() -> void
|
2017-08-09 18:24:15 +03:00
|
|
|
{
|
2017-08-17 00:02:13 +03:00
|
|
|
self->AsyncEndLayer();
|
2017-08-09 18:24:15 +03:00
|
|
|
});
|
|
|
|
|
2017-11-14 22:05:55 +03:00
|
|
|
#ifndef OMTP_FORCE_SYNC
|
|
|
|
sThread->Dispatch(task.forget());
|
|
|
|
#else
|
|
|
|
SyncRunnable::DispatchToThread(sThread, task);
|
|
|
|
#endif
|
2017-07-03 21:20:33 +03:00
|
|
|
}
|
|
|
|
|
2017-12-01 19:04:46 +03:00
|
|
|
void
|
|
|
|
PaintThread::Dispatch(RefPtr<Runnable>& aRunnable)
|
|
|
|
{
|
|
|
|
#ifndef OMTP_FORCE_SYNC
|
|
|
|
sThread->Dispatch(aRunnable.forget());
|
|
|
|
#else
|
|
|
|
SyncRunnable::DispatchToThread(sThread, aRunnable);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2017-08-09 18:24:15 +03:00
|
|
|
void
|
2017-08-17 00:02:13 +03:00
|
|
|
PaintThread::AsyncEndLayer()
|
2017-08-09 18:24:15 +03:00
|
|
|
{
|
|
|
|
MOZ_ASSERT(IsOnPaintThread());
|
|
|
|
// Textureclient forces a flush once we "end paint", so
|
|
|
|
// users of this texture expect all the drawing to be complete.
|
|
|
|
// Force a flush now.
|
|
|
|
for (size_t i = 0; i < mDrawTargetsToFlush.Length(); i++) {
|
|
|
|
mDrawTargetsToFlush[i]->Flush();
|
|
|
|
}
|
|
|
|
|
|
|
|
mDrawTargetsToFlush.Clear();
|
|
|
|
}
|
|
|
|
|
2017-08-11 07:41:31 +03:00
|
|
|
void
|
2017-08-17 00:02:13 +03:00
|
|
|
PaintThread::EndLayerTransaction(SyncObjectClient* aSyncObject)
|
2017-08-11 07:41:31 +03:00
|
|
|
{
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
|
2017-11-14 22:05:55 +03:00
|
|
|
RefPtr<CompositorBridgeChild> cbc(CompositorBridgeChild::Get());
|
2017-08-11 07:41:31 +03:00
|
|
|
RefPtr<SyncObjectClient> syncObject(aSyncObject);
|
2017-11-14 22:05:55 +03:00
|
|
|
|
|
|
|
cbc->NotifyBeginAsyncEndLayerTransaction();
|
|
|
|
|
2017-08-11 07:41:31 +03:00
|
|
|
RefPtr<PaintThread> self = this;
|
2017-08-17 00:02:13 +03:00
|
|
|
RefPtr<Runnable> task = NS_NewRunnableFunction("PaintThread::AsyncEndLayerTransaction",
|
2017-08-15 00:27:03 +03:00
|
|
|
[self, cbc, syncObject]() -> void
|
2017-08-11 07:41:31 +03:00
|
|
|
{
|
2017-08-17 00:02:13 +03:00
|
|
|
self->AsyncEndLayerTransaction(cbc, syncObject);
|
2017-08-11 07:41:31 +03:00
|
|
|
});
|
|
|
|
|
2017-11-14 22:05:55 +03:00
|
|
|
#ifndef OMTP_FORCE_SYNC
|
|
|
|
sThread->Dispatch(task.forget());
|
|
|
|
#else
|
|
|
|
SyncRunnable::DispatchToThread(sThread, task);
|
|
|
|
#endif
|
2017-08-11 07:41:31 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2017-08-17 00:02:13 +03:00
|
|
|
PaintThread::AsyncEndLayerTransaction(CompositorBridgeChild* aBridge,
|
2017-08-16 09:04:41 +03:00
|
|
|
SyncObjectClient* aSyncObject)
|
2017-08-11 07:41:31 +03:00
|
|
|
{
|
|
|
|
MOZ_ASSERT(IsOnPaintThread());
|
2017-10-30 21:49:58 +03:00
|
|
|
MOZ_ASSERT(mInAsyncPaintGroup);
|
2017-08-11 07:41:31 +03:00
|
|
|
|
2017-08-16 09:04:41 +03:00
|
|
|
if (aSyncObject) {
|
|
|
|
aSyncObject->Synchronize();
|
|
|
|
}
|
2017-08-15 00:27:03 +03:00
|
|
|
|
2017-10-30 21:49:58 +03:00
|
|
|
mInAsyncPaintGroup = false;
|
2017-10-30 21:48:16 +03:00
|
|
|
PROFILER_TRACING("Paint", "Rasterize", TRACING_INTERVAL_END);
|
2017-10-30 21:49:58 +03:00
|
|
|
|
2017-11-14 22:05:55 +03:00
|
|
|
aBridge->NotifyFinishedAsyncEndLayerTransaction();
|
2017-08-11 07:41:31 +03:00
|
|
|
}
|
2017-08-09 18:24:15 +03:00
|
|
|
|
2017-06-09 23:30:00 +03:00
|
|
|
} // namespace layers
|
2017-06-12 22:34:10 +03:00
|
|
|
} // namespace mozilla
|