2012-05-10 06:32:54 +04:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
2011-12-16 00:07:19 +04:00
|
|
|
/* vim: set sw=2 ts=2 et tw=80 : */
|
2012-05-21 15:12:37 +04: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/. */
|
2011-12-16 00:07:19 +04:00
|
|
|
|
2016-03-22 21:08:38 +03:00
|
|
|
#include "mozilla/layers/CompositorBridgeParent.h"
|
2013-08-12 03:17:23 +04:00
|
|
|
#include <stdio.h> // for fprintf, stdout
|
|
|
|
#include <stdint.h> // for uint64_t
|
|
|
|
#include <map> // for _Rb_tree_iterator, etc
|
|
|
|
#include <utility> // for pair
|
|
|
|
#include "LayerTransactionParent.h" // for LayerTransactionParent
|
|
|
|
#include "RenderTrace.h" // for RenderTraceLayers
|
|
|
|
#include "base/message_loop.h" // for MessageLoop
|
2015-04-01 11:40:35 +03:00
|
|
|
#include "base/process.h" // for ProcessId
|
2013-08-12 03:17:23 +04:00
|
|
|
#include "base/task.h" // for CancelableTask, etc
|
|
|
|
#include "base/thread.h" // for Thread
|
|
|
|
#include "gfxContext.h" // for gfxContext
|
|
|
|
#include "gfxPlatform.h" // for gfxPlatform
|
2016-03-10 12:20:40 +03:00
|
|
|
#include "TreeTraversal.h" // for ForEachNode
|
2014-07-23 03:02:25 +04:00
|
|
|
#ifdef MOZ_WIDGET_GTK
|
|
|
|
#include "gfxPlatformGtk.h" // for gfxPlatform
|
|
|
|
#endif
|
2014-02-27 06:52:54 +04:00
|
|
|
#include "gfxPrefs.h" // for gfxPrefs
|
2013-08-12 03:17:23 +04:00
|
|
|
#include "mozilla/AutoRestore.h" // for AutoRestore
|
2015-01-13 21:26:26 +03:00
|
|
|
#include "mozilla/ClearOnShutdown.h" // for ClearOnShutdown
|
2013-08-12 03:17:23 +04:00
|
|
|
#include "mozilla/DebugOnly.h" // for DebugOnly
|
2016-01-08 22:17:39 +03:00
|
|
|
#include "mozilla/dom/ContentParent.h"
|
2016-07-23 02:36:45 +03:00
|
|
|
#include "mozilla/dom/TabParent.h"
|
2013-09-27 04:37:19 +04:00
|
|
|
#include "mozilla/gfx/2D.h" // for DrawTarget
|
2013-08-12 03:17:23 +04:00
|
|
|
#include "mozilla/gfx/Point.h" // for IntSize
|
2015-04-21 18:04:57 +03:00
|
|
|
#include "mozilla/gfx/Rect.h" // for IntSize
|
2015-09-18 00:23:13 +03:00
|
|
|
#include "VRManager.h" // for VRManager
|
2013-08-12 03:17:23 +04:00
|
|
|
#include "mozilla/ipc/Transport.h" // for Transport
|
|
|
|
#include "mozilla/layers/APZCTreeManager.h" // for APZCTreeManager
|
2015-04-14 19:24:32 +03:00
|
|
|
#include "mozilla/layers/APZThreadUtils.h" // for APZCTreeManager
|
2013-08-12 03:17:23 +04:00
|
|
|
#include "mozilla/layers/AsyncCompositionManager.h"
|
|
|
|
#include "mozilla/layers/BasicCompositor.h" // for BasicCompositor
|
|
|
|
#include "mozilla/layers/Compositor.h" // for Compositor
|
|
|
|
#include "mozilla/layers/CompositorOGL.h" // for CompositorOGL
|
2016-05-16 09:38:34 +03:00
|
|
|
#include "mozilla/layers/CompositorThread.h"
|
2013-08-12 03:17:23 +04:00
|
|
|
#include "mozilla/layers/CompositorTypes.h"
|
2015-06-08 19:53:41 +03:00
|
|
|
#include "mozilla/layers/FrameUniformityData.h"
|
2015-07-06 06:02:26 +03:00
|
|
|
#include "mozilla/layers/ImageBridgeParent.h"
|
2013-08-12 03:17:23 +04:00
|
|
|
#include "mozilla/layers/LayerManagerComposite.h"
|
|
|
|
#include "mozilla/layers/LayersTypes.h"
|
|
|
|
#include "mozilla/layers/PLayerTransactionParent.h"
|
2016-01-08 22:17:39 +03:00
|
|
|
#include "mozilla/layers/RemoteContentController.h"
|
2014-10-27 15:57:36 +03:00
|
|
|
#include "mozilla/layers/ShadowLayersManager.h" // for ShadowLayersManager
|
2016-01-08 22:17:39 +03:00
|
|
|
#include "mozilla/layout/RenderFrameParent.h"
|
2015-07-05 21:56:04 +03:00
|
|
|
#include "mozilla/media/MediaSystemResourceService.h" // for MediaSystemResourceService
|
2013-08-12 03:17:23 +04:00
|
|
|
#include "mozilla/mozalloc.h" // for operator new, etc
|
2014-12-11 05:15:48 +03:00
|
|
|
#include "mozilla/Telemetry.h"
|
2014-07-23 03:02:25 +04:00
|
|
|
#ifdef MOZ_WIDGET_GTK
|
|
|
|
#include "basic/X11BasicCompositor.h" // for X11BasicCompositor
|
|
|
|
#endif
|
2013-08-12 03:17:23 +04:00
|
|
|
#include "nsCOMPtr.h" // for already_AddRefed
|
2015-02-10 01:34:50 +03:00
|
|
|
#include "nsDebug.h" // for NS_ASSERTION, etc
|
2014-02-27 01:36:35 +04:00
|
|
|
#include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc
|
2013-08-12 03:17:23 +04:00
|
|
|
#include "nsIWidget.h" // for nsIWidget
|
|
|
|
#include "nsTArray.h" // for nsTArray
|
|
|
|
#include "nsThreadUtils.h" // for NS_IsMainThread
|
|
|
|
#include "nsXULAppAPI.h" // for XRE_GetIOMessageLoop
|
2013-05-03 21:34:29 +04:00
|
|
|
#ifdef XP_WIN
|
|
|
|
#include "mozilla/layers/CompositorD3D11.h"
|
2013-08-04 11:46:17 +04:00
|
|
|
#include "mozilla/layers/CompositorD3D9.h"
|
2013-05-03 21:34:29 +04:00
|
|
|
#endif
|
2013-09-10 23:56:49 +04:00
|
|
|
#include "GeckoProfiler.h"
|
2013-06-03 14:14:37 +04:00
|
|
|
#include "mozilla/ipc/ProtocolTypes.h"
|
2014-03-07 07:24:32 +04:00
|
|
|
#include "mozilla/unused.h"
|
2014-05-05 19:38:00 +04:00
|
|
|
#include "mozilla/Hal.h"
|
|
|
|
#include "mozilla/HalTypes.h"
|
2014-07-04 22:04:11 +04:00
|
|
|
#include "mozilla/StaticPtr.h"
|
2016-07-05 22:41:21 +03:00
|
|
|
#include "mozilla/Telemetry.h"
|
2014-10-02 00:01:59 +04:00
|
|
|
#ifdef MOZ_ENABLE_PROFILER_SPS
|
|
|
|
#include "ProfilerMarkers.h"
|
|
|
|
#endif
|
2014-10-22 02:40:54 +04:00
|
|
|
#include "mozilla/VsyncDispatcher.h"
|
2016-07-18 11:54:02 +03:00
|
|
|
#if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
|
|
|
|
#include "VsyncSource.h"
|
|
|
|
#endif
|
2016-07-01 11:15:16 +03:00
|
|
|
#include "mozilla/widget/CompositorWidget.h"
|
|
|
|
#ifdef MOZ_WIDGET_SUPPORTS_OOP_COMPOSITING
|
|
|
|
# include "mozilla/widget/CompositorWidgetParent.h"
|
|
|
|
#endif
|
2012-07-13 23:38:09 +04:00
|
|
|
|
2014-10-30 18:48:42 +03:00
|
|
|
#ifdef MOZ_WIDGET_GONK
|
|
|
|
#include "GeckoTouchDispatcher.h"
|
2016-01-19 22:58:00 +03:00
|
|
|
#include "nsScreenManagerGonk.h"
|
2014-10-30 18:48:42 +03:00
|
|
|
#endif
|
|
|
|
|
2015-08-03 09:11:00 +03:00
|
|
|
#include "LayerScope.h"
|
|
|
|
|
2014-05-22 14:11:45 +04:00
|
|
|
namespace mozilla {
|
2015-09-18 00:23:13 +03:00
|
|
|
|
2014-05-22 14:11:45 +04:00
|
|
|
namespace layers {
|
|
|
|
|
2012-07-18 03:59:45 +04:00
|
|
|
using namespace mozilla::ipc;
|
2013-09-27 04:37:19 +04:00
|
|
|
using namespace mozilla::gfx;
|
2012-07-18 03:59:45 +04:00
|
|
|
using namespace std;
|
2012-03-13 00:32:02 +04:00
|
|
|
|
2015-04-01 11:40:35 +03:00
|
|
|
using base::ProcessId;
|
2015-02-11 23:01:26 +03:00
|
|
|
using base::Thread;
|
|
|
|
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::LayerTreeState::LayerTreeState()
|
2013-08-01 02:20:24 +04:00
|
|
|
: mParent(nullptr)
|
2013-12-09 05:40:58 +04:00
|
|
|
, mLayerManager(nullptr)
|
2013-12-20 00:19:25 +04:00
|
|
|
, mCrossProcessParent(nullptr)
|
2014-05-29 01:42:14 +04:00
|
|
|
, mLayerTree(nullptr)
|
2015-01-29 22:41:55 +03:00
|
|
|
, mUpdatedPluginDataAvailable(false)
|
2016-03-25 11:35:07 +03:00
|
|
|
, mPendingCompositorUpdates(0)
|
2013-08-01 02:20:24 +04:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::LayerTreeState::~LayerTreeState()
|
2015-01-29 20:57:55 +03:00
|
|
|
{
|
|
|
|
if (mController) {
|
|
|
|
mController->Destroy();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-03-22 21:08:38 +03:00
|
|
|
typedef map<uint64_t, CompositorBridgeParent::LayerTreeState> LayerTreeMap;
|
2013-07-24 01:53:22 +04:00
|
|
|
static LayerTreeMap sIndirectLayerTrees;
|
2015-01-13 21:26:26 +03:00
|
|
|
static StaticAutoPtr<mozilla::Monitor> sIndirectLayerTreesLock;
|
|
|
|
|
|
|
|
static void EnsureLayerTreeMapReady()
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
if (!sIndirectLayerTreesLock) {
|
|
|
|
sIndirectLayerTreesLock = new Monitor("IndirectLayerTree");
|
|
|
|
mozilla::ClearOnShutdown(&sIndirectLayerTreesLock);
|
|
|
|
}
|
|
|
|
}
|
2013-07-24 01:53:22 +04:00
|
|
|
|
2016-02-29 09:53:12 +03:00
|
|
|
template <typename Lambda>
|
|
|
|
inline void
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::ForEachIndirectLayerTree(const Lambda& aCallback)
|
2016-02-29 09:53:12 +03:00
|
|
|
{
|
|
|
|
sIndirectLayerTreesLock->AssertCurrentThreadOwns();
|
|
|
|
for (auto it = sIndirectLayerTrees.begin(); it != sIndirectLayerTrees.end(); it++) {
|
|
|
|
LayerTreeState* state = &it->second;
|
|
|
|
if (state->mParent == this) {
|
|
|
|
aCallback(state, it->first);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-04 22:04:11 +04:00
|
|
|
/**
|
|
|
|
* A global map referencing each compositor by ID.
|
|
|
|
*
|
|
|
|
* This map is used by the ImageBridge protocol to trigger
|
|
|
|
* compositions without having to keep references to the
|
|
|
|
* compositor
|
|
|
|
*/
|
2016-03-22 21:08:38 +03:00
|
|
|
typedef map<uint64_t,CompositorBridgeParent*> CompositorMap;
|
2016-05-16 09:38:34 +03:00
|
|
|
static StaticAutoPtr<CompositorMap> sCompositorMap;
|
2014-07-04 22:04:11 +04:00
|
|
|
|
2016-07-18 11:54:02 +03:00
|
|
|
#if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
|
|
|
|
static TimeDuration
|
|
|
|
GetGlobalVsyncRate()
|
|
|
|
{
|
|
|
|
return gfxPlatform::GetPlatform()->GetHardwareVsync()->
|
|
|
|
GetGlobalDisplay().GetVsyncRate();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2016-05-16 09:38:34 +03:00
|
|
|
void
|
2016-07-18 07:24:27 +03:00
|
|
|
CompositorBridgeParent::Setup()
|
2014-07-04 04:37:05 +04:00
|
|
|
{
|
2016-05-16 09:38:34 +03:00
|
|
|
EnsureLayerTreeMapReady();
|
|
|
|
|
2014-07-04 22:04:11 +04:00
|
|
|
MOZ_ASSERT(!sCompositorMap);
|
|
|
|
sCompositorMap = new CompositorMap;
|
2014-07-05 05:24:32 +04:00
|
|
|
}
|
2014-07-03 22:53:27 +04:00
|
|
|
|
2016-05-16 09:38:34 +03:00
|
|
|
void
|
|
|
|
CompositorBridgeParent::Shutdown()
|
2014-07-05 05:24:32 +04:00
|
|
|
{
|
2014-07-04 22:04:11 +04:00
|
|
|
MOZ_ASSERT(sCompositorMap);
|
|
|
|
MOZ_ASSERT(sCompositorMap->empty());
|
|
|
|
sCompositorMap = nullptr;
|
2014-07-05 05:24:32 +04:00
|
|
|
}
|
2014-07-03 22:53:27 +04:00
|
|
|
|
2016-05-16 09:38:34 +03:00
|
|
|
void
|
|
|
|
CompositorBridgeParent::FinishShutdown()
|
2014-07-04 22:04:11 +04:00
|
|
|
{
|
2016-05-16 09:38:34 +03:00
|
|
|
// TODO: this should be empty by now...
|
|
|
|
sIndirectLayerTrees.clear();
|
2014-07-04 22:04:11 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void SetThreadPriority()
|
|
|
|
{
|
|
|
|
hal::SetCurrentThreadPriority(hal::THREAD_PRIORITY_COMPOSITOR);
|
|
|
|
}
|
|
|
|
|
2015-08-21 03:57:42 +03:00
|
|
|
#ifdef COMPOSITOR_PERFORMANCE_WARNING
|
2015-04-30 21:35:13 +03:00
|
|
|
static int32_t
|
|
|
|
CalculateCompositionFrameRate()
|
|
|
|
{
|
2015-08-21 03:57:42 +03:00
|
|
|
// Used when layout.frame_rate is -1. Needs to be kept in sync with
|
|
|
|
// DEFAULT_FRAME_RATE in nsRefreshDriver.cpp.
|
|
|
|
// TODO: This should actually return the vsync rate.
|
|
|
|
const int32_t defaultFrameRate = 60;
|
2015-04-30 21:35:13 +03:00
|
|
|
int32_t compositionFrameRatePref = gfxPrefs::LayersCompositionFrameRate();
|
|
|
|
if (compositionFrameRatePref < 0) {
|
|
|
|
// Use the same frame rate for composition as for layout.
|
|
|
|
int32_t layoutFrameRatePref = gfxPrefs::LayoutFrameRate();
|
|
|
|
if (layoutFrameRatePref < 0) {
|
|
|
|
// TODO: The main thread frame scheduling code consults the actual
|
|
|
|
// monitor refresh rate in this case. We should do the same.
|
2015-08-21 03:57:42 +03:00
|
|
|
return defaultFrameRate;
|
2015-04-30 21:35:13 +03:00
|
|
|
}
|
|
|
|
return layoutFrameRatePref;
|
|
|
|
}
|
|
|
|
return compositionFrameRatePref;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
CompositorVsyncScheduler::Observer::Observer(CompositorVsyncScheduler* aOwner)
|
|
|
|
: mMutex("CompositorVsyncScheduler.Observer.Mutex")
|
|
|
|
, mOwner(aOwner)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
CompositorVsyncScheduler::Observer::~Observer()
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(!mOwner);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
CompositorVsyncScheduler::Observer::NotifyVsync(TimeStamp aVsyncTimestamp)
|
|
|
|
{
|
|
|
|
MutexAutoLock lock(mMutex);
|
|
|
|
if (!mOwner) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return mOwner->NotifyVsync(aVsyncTimestamp);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
CompositorVsyncScheduler::Observer::Destroy()
|
|
|
|
{
|
|
|
|
MutexAutoLock lock(mMutex);
|
|
|
|
mOwner = nullptr;
|
|
|
|
}
|
|
|
|
|
2016-05-04 03:39:23 +03:00
|
|
|
CompositorVsyncScheduler::CompositorVsyncScheduler(CompositorBridgeParent* aCompositorBridgeParent,
|
2016-07-01 11:15:16 +03:00
|
|
|
widget::CompositorWidget* aWidget)
|
2016-03-22 21:08:38 +03:00
|
|
|
: mCompositorBridgeParent(aCompositorBridgeParent)
|
2015-08-21 03:57:42 +03:00
|
|
|
, mLastCompose(TimeStamp::Now())
|
2014-10-22 02:40:54 +04:00
|
|
|
, mIsObservingVsync(false)
|
2015-11-19 02:49:58 +03:00
|
|
|
, mNeedsComposite(0)
|
2015-01-06 00:52:49 +03:00
|
|
|
, mVsyncNotificationsSkipped(0)
|
2016-07-19 21:56:07 +03:00
|
|
|
, mWidget(aWidget)
|
2014-10-22 02:40:54 +04:00
|
|
|
, mCurrentCompositeTaskMonitor("CurrentCompositeTaskMonitor")
|
2016-01-19 22:58:00 +03:00
|
|
|
, mCurrentCompositeTask(nullptr)
|
2015-01-22 03:13:15 +03:00
|
|
|
, mSetNeedsCompositeMonitor("SetNeedsCompositeMonitor")
|
|
|
|
, mSetNeedsCompositeTask(nullptr)
|
2016-01-19 22:58:00 +03:00
|
|
|
#ifdef MOZ_WIDGET_GONK
|
|
|
|
#if ANDROID_VERSION >= 19
|
|
|
|
, mDisplayEnabled(false)
|
|
|
|
, mSetDisplayMonitor("SetDisplayMonitor")
|
|
|
|
, mSetDisplayTask(nullptr)
|
|
|
|
#endif
|
|
|
|
#endif
|
2014-10-22 02:40:54 +04:00
|
|
|
{
|
2016-07-19 21:56:07 +03:00
|
|
|
MOZ_ASSERT(NS_IsMainThread() || XRE_GetProcessType() == GeckoProcessType_GPU);
|
2015-04-30 21:35:13 +03:00
|
|
|
mVsyncObserver = new Observer(this);
|
2014-12-18 19:30:06 +03:00
|
|
|
#ifdef MOZ_WIDGET_GONK
|
2015-04-30 21:35:13 +03:00
|
|
|
GeckoTouchDispatcher::GetInstance()->SetCompositorVsyncScheduler(this);
|
2016-01-19 22:58:00 +03:00
|
|
|
|
|
|
|
#if ANDROID_VERSION >= 19
|
|
|
|
RefPtr<nsScreenManagerGonk> screenManager = nsScreenManagerGonk::GetInstance();
|
|
|
|
screenManager->SetCompositorVsyncScheduler(this);
|
|
|
|
#endif
|
2014-12-18 19:30:06 +03:00
|
|
|
#endif
|
2015-08-21 03:57:42 +03:00
|
|
|
|
|
|
|
// mAsapScheduling is set on the main thread during init,
|
|
|
|
// but is only accessed after on the compositor thread.
|
|
|
|
mAsapScheduling = gfxPrefs::LayersCompositionFrameRate() == 0 ||
|
|
|
|
gfxPlatform::IsInLayoutAsapMode();
|
2014-10-22 02:40:54 +04:00
|
|
|
}
|
|
|
|
|
2015-04-30 21:35:13 +03:00
|
|
|
CompositorVsyncScheduler::~CompositorVsyncScheduler()
|
2014-10-22 02:40:54 +04:00
|
|
|
{
|
2014-12-18 19:30:06 +03:00
|
|
|
MOZ_ASSERT(!mIsObservingVsync);
|
2015-04-30 21:35:13 +03:00
|
|
|
MOZ_ASSERT(!mVsyncObserver);
|
2014-12-19 23:52:42 +03:00
|
|
|
// The CompositorVsyncDispatcher is cleaned up before this in the nsBaseWidget, which stops vsync listeners
|
2016-03-22 21:08:38 +03:00
|
|
|
mCompositorBridgeParent = nullptr;
|
2015-01-22 03:13:15 +03:00
|
|
|
}
|
|
|
|
|
2016-01-19 22:58:00 +03:00
|
|
|
#ifdef MOZ_WIDGET_GONK
|
|
|
|
#if ANDROID_VERSION >= 19
|
|
|
|
void
|
|
|
|
CompositorVsyncScheduler::SetDisplay(bool aDisplayEnable)
|
|
|
|
{
|
|
|
|
// SetDisplay() is usually called from nsScreenManager at main thread. Post
|
|
|
|
// to compositor thread if needs.
|
2016-05-16 09:40:13 +03:00
|
|
|
if (!CompositorThreadHolder::IsInCompositorThread()) {
|
2016-01-19 22:58:00 +03:00
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
MonitorAutoLock lock(mSetDisplayMonitor);
|
2016-04-28 03:06:05 +03:00
|
|
|
RefPtr<CancelableRunnable> task =
|
2016-05-05 11:45:00 +03:00
|
|
|
NewCancelableRunnableMethod<bool>(this, &CompositorVsyncScheduler::SetDisplay, aDisplayEnable);
|
2016-04-28 03:06:05 +03:00
|
|
|
mSetDisplayTask = task;
|
|
|
|
ScheduleTask(task.forget(), 0);
|
2016-01-19 22:58:00 +03:00
|
|
|
return;
|
|
|
|
} else {
|
|
|
|
MonitorAutoLock lock(mSetDisplayMonitor);
|
|
|
|
mSetDisplayTask = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mDisplayEnabled == aDisplayEnable) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
mDisplayEnabled = aDisplayEnable;
|
|
|
|
if (!mDisplayEnabled) {
|
|
|
|
CancelCurrentSetNeedsCompositeTask();
|
|
|
|
CancelCurrentCompositeTask();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
CompositorVsyncScheduler::CancelSetDisplayTask()
|
|
|
|
{
|
2016-05-16 09:40:13 +03:00
|
|
|
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
2016-01-19 22:58:00 +03:00
|
|
|
MonitorAutoLock lock(mSetDisplayMonitor);
|
|
|
|
if (mSetDisplayTask) {
|
|
|
|
mSetDisplayTask->Cancel();
|
|
|
|
mSetDisplayTask = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
// CancelSetDisplayTask is only be called in clean-up process, so
|
|
|
|
// mDisplayEnabled could be false there.
|
|
|
|
mDisplayEnabled = false;
|
|
|
|
}
|
|
|
|
#endif //ANDROID_VERSION >= 19
|
|
|
|
#endif //MOZ_WIDGET_GONK
|
|
|
|
|
2015-01-22 03:13:15 +03:00
|
|
|
void
|
2015-04-30 21:35:13 +03:00
|
|
|
CompositorVsyncScheduler::Destroy()
|
2015-01-22 03:13:15 +03:00
|
|
|
{
|
2015-11-24 04:50:51 +03:00
|
|
|
if (!mVsyncObserver) {
|
|
|
|
// Destroy was already called on this object.
|
|
|
|
return;
|
|
|
|
}
|
2016-05-16 09:40:13 +03:00
|
|
|
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
2015-01-22 03:13:15 +03:00
|
|
|
UnobserveVsync();
|
2015-04-30 21:35:13 +03:00
|
|
|
mVsyncObserver->Destroy();
|
|
|
|
mVsyncObserver = nullptr;
|
2016-01-19 22:58:00 +03:00
|
|
|
|
|
|
|
#ifdef MOZ_WIDGET_GONK
|
|
|
|
#if ANDROID_VERSION >= 19
|
|
|
|
CancelSetDisplayTask();
|
|
|
|
#endif
|
|
|
|
#endif
|
2015-01-22 03:13:15 +03:00
|
|
|
CancelCurrentSetNeedsCompositeTask();
|
2015-08-21 03:57:42 +03:00
|
|
|
CancelCurrentCompositeTask();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
CompositorVsyncScheduler::PostCompositeTask(TimeStamp aCompositeTimestamp)
|
|
|
|
{
|
|
|
|
// can be called from the compositor or vsync thread
|
|
|
|
MonitorAutoLock lock(mCurrentCompositeTaskMonitor);
|
2016-07-08 03:52:58 +03:00
|
|
|
if (mCurrentCompositeTask == nullptr && CompositorThreadHolder::Loop()) {
|
2016-04-28 03:06:05 +03:00
|
|
|
RefPtr<CancelableRunnable> task =
|
2016-05-05 11:45:00 +03:00
|
|
|
NewCancelableRunnableMethod<TimeStamp>(this, &CompositorVsyncScheduler::Composite,
|
|
|
|
aCompositeTimestamp);
|
2016-04-28 03:06:05 +03:00
|
|
|
mCurrentCompositeTask = task;
|
|
|
|
ScheduleTask(task.forget(), 0);
|
2015-08-21 03:57:42 +03:00
|
|
|
}
|
2015-04-30 21:35:13 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
CompositorVsyncScheduler::ScheduleComposition()
|
|
|
|
{
|
2016-05-16 09:40:13 +03:00
|
|
|
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
2015-08-21 03:57:42 +03:00
|
|
|
if (mAsapScheduling) {
|
|
|
|
// Used only for performance testing purposes
|
|
|
|
PostCompositeTask(TimeStamp::Now());
|
2015-11-19 02:49:58 +03:00
|
|
|
#ifdef MOZ_WIDGET_ANDROID
|
|
|
|
} else if (mNeedsComposite >= 2 && mIsObservingVsync) {
|
|
|
|
// uh-oh, we already requested a composite at least twice so far, and a
|
|
|
|
// composite hasn't happened yet. It is possible that the vsync observation
|
|
|
|
// is blocked on the main thread, so let's just composite ASAP and not
|
|
|
|
// wait for the vsync. Note that this should only ever happen on Fennec
|
|
|
|
// because there content runs in the same process as the compositor, and so
|
|
|
|
// content can actually block the main thread in this process.
|
|
|
|
PostCompositeTask(TimeStamp::Now());
|
|
|
|
#endif
|
2015-08-21 03:57:42 +03:00
|
|
|
} else {
|
2015-11-19 02:49:58 +03:00
|
|
|
SetNeedsComposite();
|
2015-08-21 03:57:42 +03:00
|
|
|
}
|
2015-01-22 03:13:15 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2015-04-30 21:35:13 +03:00
|
|
|
CompositorVsyncScheduler::CancelCurrentSetNeedsCompositeTask()
|
2015-01-22 03:13:15 +03:00
|
|
|
{
|
2016-05-16 09:40:13 +03:00
|
|
|
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
2015-01-22 03:13:15 +03:00
|
|
|
MonitorAutoLock lock(mSetNeedsCompositeMonitor);
|
|
|
|
if (mSetNeedsCompositeTask) {
|
|
|
|
mSetNeedsCompositeTask->Cancel();
|
|
|
|
mSetNeedsCompositeTask = nullptr;
|
|
|
|
}
|
2015-11-19 02:49:58 +03:00
|
|
|
mNeedsComposite = 0;
|
2014-10-22 02:40:54 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* TODO Potential performance heuristics:
|
|
|
|
* If a composite takes 17 ms, do we composite ASAP or wait until next vsync?
|
|
|
|
* If a layer transaction comes after vsync, do we composite ASAP or wait until
|
|
|
|
* next vsync?
|
|
|
|
* How many skipped vsync events until we stop listening to vsync events?
|
|
|
|
*/
|
|
|
|
void
|
2015-11-19 02:49:58 +03:00
|
|
|
CompositorVsyncScheduler::SetNeedsComposite()
|
2014-10-22 02:40:54 +04:00
|
|
|
{
|
2016-05-16 09:40:13 +03:00
|
|
|
if (!CompositorThreadHolder::IsInCompositorThread()) {
|
2015-01-22 03:13:15 +03:00
|
|
|
MonitorAutoLock lock(mSetNeedsCompositeMonitor);
|
2016-04-28 03:06:05 +03:00
|
|
|
RefPtr<CancelableRunnable> task =
|
2016-05-05 11:45:00 +03:00
|
|
|
NewCancelableRunnableMethod(this, &CompositorVsyncScheduler::SetNeedsComposite);
|
2016-04-28 03:06:05 +03:00
|
|
|
mSetNeedsCompositeTask = task;
|
|
|
|
ScheduleTask(task.forget(), 0);
|
2015-01-22 03:13:15 +03:00
|
|
|
return;
|
|
|
|
} else {
|
|
|
|
MonitorAutoLock lock(mSetNeedsCompositeMonitor);
|
|
|
|
mSetNeedsCompositeTask = nullptr;
|
2014-12-18 19:30:06 +03:00
|
|
|
}
|
2014-10-22 02:40:54 +04:00
|
|
|
|
2016-01-19 22:58:00 +03:00
|
|
|
#ifdef MOZ_WIDGET_GONK
|
|
|
|
#if ANDROID_VERSION >= 19
|
|
|
|
// Skip composition when display off.
|
|
|
|
if (!mDisplayEnabled) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
2015-11-19 02:49:58 +03:00
|
|
|
mNeedsComposite++;
|
2014-10-22 02:40:54 +04:00
|
|
|
if (!mIsObservingVsync && mNeedsComposite) {
|
|
|
|
ObserveVsync();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2015-04-30 21:35:13 +03:00
|
|
|
CompositorVsyncScheduler::NotifyVsync(TimeStamp aVsyncTimestamp)
|
2014-10-22 02:40:54 +04:00
|
|
|
{
|
2016-07-19 21:56:07 +03:00
|
|
|
// Called from the vsync dispatch thread. When in the GPU Process, that's
|
|
|
|
// the same as the compositor thread.
|
|
|
|
MOZ_ASSERT_IF(XRE_IsParentProcess(), !CompositorThreadHolder::IsInCompositorThread());
|
|
|
|
MOZ_ASSERT_IF(XRE_GetProcessType() == GeckoProcessType_GPU, CompositorThreadHolder::IsInCompositorThread());
|
2014-10-22 02:40:54 +04:00
|
|
|
MOZ_ASSERT(!NS_IsMainThread());
|
2015-08-21 03:57:42 +03:00
|
|
|
PostCompositeTask(aVsyncTimestamp);
|
2014-10-22 02:40:54 +04:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2015-04-30 21:35:13 +03:00
|
|
|
CompositorVsyncScheduler::CancelCurrentCompositeTask()
|
2014-10-22 02:40:54 +04:00
|
|
|
{
|
2016-05-16 09:40:13 +03:00
|
|
|
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread() || NS_IsMainThread());
|
2014-10-22 02:40:54 +04:00
|
|
|
MonitorAutoLock lock(mCurrentCompositeTaskMonitor);
|
2015-08-21 03:57:42 +03:00
|
|
|
if (mCurrentCompositeTask) {
|
|
|
|
mCurrentCompositeTask->Cancel();
|
|
|
|
mCurrentCompositeTask = nullptr;
|
|
|
|
}
|
2014-10-22 02:40:54 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2016-01-21 18:47:31 +03:00
|
|
|
CompositorVsyncScheduler::Composite(TimeStamp aVsyncTimestamp)
|
2014-10-22 02:40:54 +04:00
|
|
|
{
|
2016-05-16 09:40:13 +03:00
|
|
|
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
2014-10-22 02:40:54 +04:00
|
|
|
{
|
|
|
|
MonitorAutoLock lock(mCurrentCompositeTaskMonitor);
|
|
|
|
mCurrentCompositeTask = nullptr;
|
|
|
|
}
|
|
|
|
|
2016-02-05 21:11:48 +03:00
|
|
|
if ((aVsyncTimestamp < mLastCompose) && !mAsapScheduling) {
|
|
|
|
// We can sometimes get vsync timestamps that are in the past
|
|
|
|
// compared to the last compose with force composites.
|
|
|
|
// In those cases, wait until the next vsync;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-03-30 18:12:47 +03:00
|
|
|
DispatchTouchEvents(aVsyncTimestamp);
|
2015-09-18 00:23:13 +03:00
|
|
|
DispatchVREvents(aVsyncTimestamp);
|
2015-03-30 18:12:47 +03:00
|
|
|
|
2015-08-21 03:57:42 +03:00
|
|
|
if (mNeedsComposite || mAsapScheduling) {
|
2015-11-19 02:49:58 +03:00
|
|
|
mNeedsComposite = 0;
|
2015-04-30 21:35:13 +03:00
|
|
|
mLastCompose = aVsyncTimestamp;
|
2016-01-21 18:47:31 +03:00
|
|
|
ComposeToTarget(nullptr);
|
2015-01-06 00:52:49 +03:00
|
|
|
mVsyncNotificationsSkipped = 0;
|
2015-11-05 21:24:12 +03:00
|
|
|
|
|
|
|
TimeDuration compositeFrameTotal = TimeStamp::Now() - aVsyncTimestamp;
|
|
|
|
mozilla::Telemetry::Accumulate(mozilla::Telemetry::COMPOSITE_FRAME_ROUNDTRIP_TIME,
|
|
|
|
compositeFrameTotal.ToMilliseconds());
|
2015-01-06 00:52:49 +03:00
|
|
|
} else if (mVsyncNotificationsSkipped++ > gfxPrefs::CompositorUnobserveCount()) {
|
|
|
|
UnobserveVsync();
|
2014-10-22 02:40:54 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-03-07 00:58:22 +03:00
|
|
|
void
|
2015-04-30 21:35:13 +03:00
|
|
|
CompositorVsyncScheduler::OnForceComposeToTarget()
|
2015-03-07 00:58:22 +03:00
|
|
|
{
|
|
|
|
/**
|
|
|
|
* bug 1138502 - There are cases such as during long-running window resizing events
|
|
|
|
* where we receive many sync RecvFlushComposites. We also get vsync notifications which
|
|
|
|
* will increment mVsyncNotificationsSkipped because a composite just occurred. After
|
|
|
|
* enough vsyncs and RecvFlushComposites occurred, we will disable vsync. Then at the next
|
|
|
|
* ScheduleComposite, we will enable vsync, then get a RecvFlushComposite, which will
|
|
|
|
* force us to unobserve vsync again. On some platforms, enabling/disabling vsync is not
|
|
|
|
* free and this oscillating behavior causes a performance hit. In order to avoid this problem,
|
|
|
|
* we reset the mVsyncNotificationsSkipped counter to keep vsync enabled.
|
|
|
|
*/
|
2016-05-16 09:40:13 +03:00
|
|
|
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
2015-03-07 00:58:22 +03:00
|
|
|
mVsyncNotificationsSkipped = 0;
|
|
|
|
}
|
|
|
|
|
2015-04-30 21:35:13 +03:00
|
|
|
void
|
2015-05-07 12:07:53 +03:00
|
|
|
CompositorVsyncScheduler::ForceComposeToTarget(gfx::DrawTarget* aTarget, const IntRect* aRect)
|
2015-04-30 21:35:13 +03:00
|
|
|
{
|
2016-05-16 09:40:13 +03:00
|
|
|
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
2015-04-30 21:35:13 +03:00
|
|
|
OnForceComposeToTarget();
|
2016-01-21 18:47:31 +03:00
|
|
|
mLastCompose = TimeStamp::Now();
|
|
|
|
ComposeToTarget(aTarget, aRect);
|
2015-04-30 21:35:13 +03:00
|
|
|
}
|
|
|
|
|
2014-10-22 02:40:54 +04:00
|
|
|
bool
|
2015-04-30 21:35:13 +03:00
|
|
|
CompositorVsyncScheduler::NeedsComposite()
|
2014-10-22 02:40:54 +04:00
|
|
|
{
|
2016-05-16 09:40:13 +03:00
|
|
|
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
2014-10-22 02:40:54 +04:00
|
|
|
return mNeedsComposite;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2015-04-30 21:35:13 +03:00
|
|
|
CompositorVsyncScheduler::ObserveVsync()
|
2014-10-22 02:40:54 +04:00
|
|
|
{
|
2016-05-16 09:40:13 +03:00
|
|
|
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
2016-07-19 21:56:07 +03:00
|
|
|
mWidget->ObserveVsync(mVsyncObserver);
|
2014-10-22 02:40:54 +04:00
|
|
|
mIsObservingVsync = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2015-04-30 21:35:13 +03:00
|
|
|
CompositorVsyncScheduler::UnobserveVsync()
|
2014-10-22 02:40:54 +04:00
|
|
|
{
|
2016-05-16 09:40:13 +03:00
|
|
|
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
2016-07-19 21:56:07 +03:00
|
|
|
mWidget->ObserveVsync(nullptr);
|
2014-10-22 02:40:54 +04:00
|
|
|
mIsObservingVsync = false;
|
|
|
|
}
|
|
|
|
|
2014-10-30 18:48:42 +03:00
|
|
|
void
|
2015-04-30 21:35:13 +03:00
|
|
|
CompositorVsyncScheduler::DispatchTouchEvents(TimeStamp aVsyncTimestamp)
|
2014-10-30 18:48:42 +03:00
|
|
|
{
|
|
|
|
#ifdef MOZ_WIDGET_GONK
|
2015-02-24 23:52:16 +03:00
|
|
|
GeckoTouchDispatcher::GetInstance()->NotifyVsync(aVsyncTimestamp);
|
2014-10-30 18:48:42 +03:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2015-09-18 00:23:13 +03:00
|
|
|
void
|
|
|
|
CompositorVsyncScheduler::DispatchVREvents(TimeStamp aVsyncTimestamp)
|
|
|
|
{
|
2016-05-16 09:40:13 +03:00
|
|
|
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
2015-09-18 00:23:13 +03:00
|
|
|
|
|
|
|
VRManager* vm = VRManager::Get();
|
|
|
|
vm->NotifyVsync(aVsyncTimestamp);
|
|
|
|
}
|
|
|
|
|
2015-08-21 03:57:42 +03:00
|
|
|
void
|
2016-04-28 03:06:05 +03:00
|
|
|
CompositorVsyncScheduler::ScheduleTask(already_AddRefed<CancelableRunnable> aTask,
|
|
|
|
int aTime)
|
2015-08-21 03:57:42 +03:00
|
|
|
{
|
2016-05-16 09:39:30 +03:00
|
|
|
MOZ_ASSERT(CompositorThreadHolder::Loop());
|
2015-08-21 03:57:42 +03:00
|
|
|
MOZ_ASSERT(aTime >= 0);
|
2016-05-16 09:39:30 +03:00
|
|
|
CompositorThreadHolder::Loop()->PostDelayedTask(Move(aTask), aTime);
|
2015-08-21 03:57:42 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
CompositorVsyncScheduler::ResumeComposition()
|
2015-03-03 19:14:22 +03:00
|
|
|
{
|
2016-05-16 09:40:13 +03:00
|
|
|
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
2016-01-21 18:47:31 +03:00
|
|
|
mLastCompose = TimeStamp::Now();
|
|
|
|
ComposeToTarget(nullptr);
|
2015-03-03 19:14:22 +03:00
|
|
|
}
|
|
|
|
|
2015-08-21 03:57:42 +03:00
|
|
|
void
|
|
|
|
CompositorVsyncScheduler::ComposeToTarget(gfx::DrawTarget* aTarget, const IntRect* aRect)
|
2015-03-03 19:14:22 +03:00
|
|
|
{
|
2016-05-16 09:40:13 +03:00
|
|
|
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
2016-03-22 21:08:38 +03:00
|
|
|
MOZ_ASSERT(mCompositorBridgeParent);
|
|
|
|
mCompositorBridgeParent->CompositeToTarget(aTarget, aRect);
|
2015-03-03 19:14:22 +03:00
|
|
|
}
|
|
|
|
|
2016-05-16 09:39:30 +03:00
|
|
|
static inline MessageLoop*
|
|
|
|
CompositorLoop()
|
|
|
|
{
|
|
|
|
return CompositorThreadHolder::Loop();
|
|
|
|
}
|
|
|
|
|
2016-07-18 07:24:27 +03:00
|
|
|
CompositorBridgeParent::CompositorBridgeParent(CSSToLayoutDeviceScale aScale,
|
2016-07-26 11:57:11 +03:00
|
|
|
const TimeDuration& aVsyncRate,
|
2016-03-22 21:08:38 +03:00
|
|
|
bool aUseExternalSurfaceSize,
|
2016-06-28 03:05:34 +03:00
|
|
|
const gfx::IntSize& aSurfaceSize)
|
2016-07-20 02:59:30 +03:00
|
|
|
: mWidget(nullptr)
|
2016-07-18 07:24:27 +03:00
|
|
|
, mScale(aScale)
|
2016-07-26 11:57:11 +03:00
|
|
|
, mVsyncRate(aVsyncRate)
|
2013-05-28 03:47:45 +04:00
|
|
|
, mIsTesting(false)
|
2014-05-29 01:42:14 +04:00
|
|
|
, mPendingTransaction(0)
|
2012-02-08 21:08:03 +04:00
|
|
|
, mPaused(false)
|
2013-04-30 07:16:04 +04:00
|
|
|
, mUseExternalSurfaceSize(aUseExternalSurfaceSize)
|
2016-06-28 03:05:34 +03:00
|
|
|
, mEGLSurfaceSize(aSurfaceSize)
|
2012-05-10 06:32:54 +04:00
|
|
|
, mPauseCompositionMonitor("PauseCompositionMonitor")
|
2012-05-29 21:49:03 +04:00
|
|
|
, mResumeCompositionMonitor("ResumeCompositionMonitor")
|
2016-02-29 09:53:15 +03:00
|
|
|
, mResetCompositorMonitor("ResetCompositorMonitor")
|
2016-07-18 07:24:27 +03:00
|
|
|
, mRootLayerTreeID(0)
|
2012-11-22 06:40:57 +04:00
|
|
|
, mOverrideComposeReadiness(false)
|
2012-12-23 08:54:23 +04:00
|
|
|
, mForceCompositionTask(nullptr)
|
2016-05-16 09:38:34 +03:00
|
|
|
, mCompositorThreadHolder(CompositorThreadHolder::GetSingleton())
|
2015-04-30 21:35:13 +03:00
|
|
|
, mCompositorScheduler(nullptr)
|
2016-08-16 18:46:13 +03:00
|
|
|
, mPaintTime(TimeDuration::Forever())
|
2015-10-06 22:23:24 +03:00
|
|
|
#if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
|
|
|
|
, mLastPluginUpdateLayerTreeId(0)
|
2016-01-12 20:05:58 +03:00
|
|
|
, mDeferPluginWindows(false)
|
2016-02-04 18:10:55 +03:00
|
|
|
, mPluginWindowsHidden(false)
|
2015-10-06 22:23:24 +03:00
|
|
|
#endif
|
2016-07-18 07:24:27 +03:00
|
|
|
{
|
2016-07-18 07:24:28 +03:00
|
|
|
// Always run destructor on the main thread
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
2016-07-18 07:24:27 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2016-07-18 07:24:27 +03:00
|
|
|
CompositorBridgeParent::InitSameProcess(widget::CompositorWidget* aWidget,
|
|
|
|
const uint64_t& aLayerTreeId,
|
|
|
|
bool aUseAPZ)
|
2016-07-18 07:24:27 +03:00
|
|
|
{
|
|
|
|
mWidget = aWidget;
|
2016-07-18 07:24:27 +03:00
|
|
|
mRootLayerTreeID = aLayerTreeId;
|
2016-07-18 07:24:27 +03:00
|
|
|
if (aUseAPZ) {
|
|
|
|
mApzcTreeManager = new APZCTreeManager();
|
|
|
|
}
|
|
|
|
|
|
|
|
// IPDL initialization. mSelfRef is cleared in DeferredDestroy.
|
|
|
|
SetOtherProcessId(base::GetCurrentProcId());
|
|
|
|
mSelfRef = this;
|
|
|
|
|
|
|
|
Initialize();
|
|
|
|
}
|
|
|
|
|
2016-07-18 07:24:28 +03:00
|
|
|
bool
|
|
|
|
CompositorBridgeParent::Bind(Endpoint<PCompositorBridgeParent>&& aEndpoint)
|
|
|
|
{
|
|
|
|
if (!aEndpoint.Bind(this, nullptr)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
mSelfRef = this;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
CompositorBridgeParent::RecvInitialize(const uint64_t& aRootLayerTreeId)
|
|
|
|
{
|
|
|
|
mRootLayerTreeID = aRootLayerTreeId;
|
|
|
|
|
|
|
|
Initialize();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-07-18 07:24:27 +03:00
|
|
|
void
|
|
|
|
CompositorBridgeParent::Initialize()
|
2011-12-16 00:07:19 +04:00
|
|
|
{
|
2014-07-04 22:04:11 +04:00
|
|
|
MOZ_ASSERT(CompositorThread(),
|
2016-03-22 21:08:38 +03:00
|
|
|
"The compositor thread must be Initialized before instanciating a CompositorBridgeParent.");
|
2016-04-13 00:04:50 +03:00
|
|
|
|
2012-07-13 23:38:09 +04:00
|
|
|
mCompositorID = 0;
|
Bug 825928: Land layers refactoring. r=jrmuizel,bas,nical,mattwoodrow,roc,nrc,benwa,bjacob,jgilbert,kchen CLOSED TREE
Please contact Bas Schouten <bschouten@mozilla.com>, Nicolas Silva <nsilva@mozilla.com> or Nicholas Cameron <ncameron@mozilla.com> with general questions. Below is a rough list of authors to contact with specific questions.
Authors:
gfx/layers/Compositor.* gfx/layers/Effects.h - Compositor Interface - bas,nrc,nical
gfx/layers/d3d* - D3D9/D3D10 - bas
gfx/layers/ThebesLayer* - ThebesLayers - nrc,bas
gfx/layers/composite/* - CompositeLayers - nrc,nical
gfx/layers/client/* - Client - nrc,nical,bas
gfx/layers/*Image* - nical
gfx/layers/ipc ipc - IPC - nical
gfx/layers/opengl - CompositorOGL - nrc,nical
gfx/2d - bas,nrc
gfx/gl - GLContext - bjacob
dom/* layout/* - DOM - mattwoodrow
2013-04-10 13:20:52 +04:00
|
|
|
// FIXME: This holds on the the fact that right now the only thing that
|
|
|
|
// can destroy this instance is initialized on the compositor thread after
|
2012-07-13 23:38:09 +04:00
|
|
|
// this task has been processed.
|
2015-01-27 23:52:44 +03:00
|
|
|
MOZ_ASSERT(CompositorLoop());
|
2016-04-28 03:06:05 +03:00
|
|
|
CompositorLoop()->PostTask(NewRunnableFunction(&AddCompositor,
|
|
|
|
this, &mCompositorID));
|
2012-07-18 03:59:45 +04:00
|
|
|
|
2016-04-28 03:06:05 +03:00
|
|
|
CompositorLoop()->PostTask(NewRunnableFunction(SetThreadPriority));
|
2014-05-05 19:38:00 +04:00
|
|
|
|
2015-01-13 21:26:26 +03:00
|
|
|
|
|
|
|
{ // scope lock
|
|
|
|
MonitorAutoLock lock(*sIndirectLayerTreesLock);
|
|
|
|
sIndirectLayerTrees[mRootLayerTreeID].mParent = this;
|
|
|
|
}
|
2013-07-30 22:03:43 +04:00
|
|
|
|
2016-07-18 07:24:27 +03:00
|
|
|
LayerScope::SetPixelScale(mScale.scale);
|
2016-07-19 21:56:07 +03:00
|
|
|
|
|
|
|
mCompositorScheduler = new CompositorVsyncScheduler(this, mWidget);
|
2011-12-16 00:07:19 +04:00
|
|
|
}
|
|
|
|
|
2013-07-30 22:03:43 +04:00
|
|
|
uint64_t
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::RootLayerTreeId()
|
2013-07-30 22:03:43 +04:00
|
|
|
{
|
2016-07-18 07:24:27 +03:00
|
|
|
MOZ_ASSERT(mRootLayerTreeID);
|
2013-07-30 22:03:43 +04:00
|
|
|
return mRootLayerTreeID;
|
|
|
|
}
|
|
|
|
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::~CompositorBridgeParent()
|
2011-12-16 00:07:19 +04:00
|
|
|
{
|
2016-04-13 00:04:50 +03:00
|
|
|
InfallibleTArray<PTextureParent*> textures;
|
|
|
|
ManagedPTextureParent(textures);
|
|
|
|
// We expect all textures to be destroyed by now.
|
|
|
|
MOZ_DIAGNOSTIC_ASSERT(textures.Length() == 0);
|
|
|
|
for (unsigned int i = 0; i < textures.Length(); ++i) {
|
|
|
|
RefPtr<TextureHost> tex = TextureHost::AsTextureHost(textures[i]);
|
|
|
|
tex->DeallocateDeviceData();
|
|
|
|
}
|
2011-12-16 00:07:19 +04:00
|
|
|
}
|
|
|
|
|
2013-04-28 10:46:30 +04:00
|
|
|
void
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::ForceIsFirstPaint()
|
2013-04-28 10:46:30 +04:00
|
|
|
{
|
|
|
|
mCompositionManager->ForceIsFirstPaint();
|
2011-12-16 00:07:19 +04:00
|
|
|
}
|
|
|
|
|
2016-06-21 18:31:21 +03:00
|
|
|
void
|
|
|
|
CompositorBridgeParent::StopAndClearResources()
|
2012-03-29 17:59:22 +04:00
|
|
|
{
|
2016-06-21 18:31:21 +03:00
|
|
|
if (mForceCompositionTask) {
|
|
|
|
mForceCompositionTask->Cancel();
|
|
|
|
mForceCompositionTask = nullptr;
|
|
|
|
}
|
|
|
|
|
2012-03-29 19:26:58 +04:00
|
|
|
mPaused = true;
|
2012-03-30 23:43:11 +04:00
|
|
|
|
2016-03-22 21:08:38 +03:00
|
|
|
// Ensure that the layer manager is destroyed before CompositorBridgeChild.
|
2013-04-11 14:14:29 +04:00
|
|
|
if (mLayerManager) {
|
2015-01-13 21:26:26 +03:00
|
|
|
MonitorAutoLock lock(*sIndirectLayerTreesLock);
|
2016-02-29 09:53:12 +03:00
|
|
|
ForEachIndirectLayerTree([this] (LayerTreeState* lts, uint64_t) -> void {
|
|
|
|
mLayerManager->ClearCachedResources(lts->mRoot);
|
|
|
|
lts->mLayerManager = nullptr;
|
|
|
|
lts->mParent = nullptr;
|
|
|
|
});
|
2013-04-11 14:14:29 +04:00
|
|
|
mLayerManager->Destroy();
|
2013-04-28 10:46:30 +04:00
|
|
|
mLayerManager = nullptr;
|
|
|
|
mCompositionManager = nullptr;
|
2013-04-11 14:14:29 +04:00
|
|
|
}
|
2012-03-30 23:43:11 +04:00
|
|
|
|
2015-11-24 04:50:51 +03:00
|
|
|
if (mCompositor) {
|
|
|
|
mCompositor->DetachWidget();
|
2016-04-11 19:18:24 +03:00
|
|
|
mCompositor->Destroy();
|
|
|
|
mCompositor = nullptr;
|
2015-11-24 04:50:51 +03:00
|
|
|
}
|
2016-06-29 00:54:20 +03:00
|
|
|
|
2016-07-19 21:56:07 +03:00
|
|
|
// This must be destroyed now since it accesses the widget.
|
|
|
|
if (mCompositorScheduler) {
|
|
|
|
mCompositorScheduler->Destroy();
|
|
|
|
mCompositorScheduler = nullptr;
|
|
|
|
}
|
|
|
|
|
2016-06-29 00:54:20 +03:00
|
|
|
// After this point, it is no longer legal to access the widget.
|
2016-07-01 11:15:16 +03:00
|
|
|
mWidget = nullptr;
|
2016-06-21 18:31:21 +03:00
|
|
|
}
|
2015-11-24 04:50:51 +03:00
|
|
|
|
2016-06-21 18:31:21 +03:00
|
|
|
bool
|
|
|
|
CompositorBridgeParent::RecvWillClose()
|
|
|
|
{
|
|
|
|
StopAndClearResources();
|
2012-03-30 23:43:11 +04:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-03-22 21:08:38 +03:00
|
|
|
void CompositorBridgeParent::DeferredDestroy()
|
2014-07-04 22:04:11 +04:00
|
|
|
{
|
|
|
|
MOZ_ASSERT(!NS_IsMainThread());
|
2015-10-01 15:58:12 +03:00
|
|
|
MOZ_ASSERT(mCompositorThreadHolder);
|
2014-07-04 22:04:12 +04:00
|
|
|
mCompositorThreadHolder = nullptr;
|
2015-11-24 04:50:51 +03:00
|
|
|
mSelfRef = nullptr;
|
2011-12-17 04:21:51 +04:00
|
|
|
}
|
|
|
|
|
2012-03-29 02:00:10 +04:00
|
|
|
bool
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::RecvPause()
|
2012-03-29 02:00:10 +04:00
|
|
|
{
|
|
|
|
PauseComposition();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::RecvResume()
|
2012-03-29 02:00:10 +04:00
|
|
|
{
|
|
|
|
ResumeComposition();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2012-10-04 11:05:24 +04:00
|
|
|
bool
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::RecvMakeSnapshot(const SurfaceDescriptor& aInSnapshot,
|
|
|
|
const gfx::IntRect& aRect)
|
2012-10-04 11:05:24 +04:00
|
|
|
{
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<DrawTarget> target = GetDrawTargetForDescriptor(aInSnapshot, gfx::BackendType::CAIRO);
|
2016-01-06 15:56:00 +03:00
|
|
|
MOZ_ASSERT(target);
|
|
|
|
if (!target) {
|
|
|
|
// We kill the content process rather than have it continue with an invalid
|
|
|
|
// snapshot, that may be too harsh and we could decide to return some sort
|
|
|
|
// of error to the child process and let it deal with it...
|
|
|
|
return false;
|
|
|
|
}
|
2014-05-28 05:21:32 +04:00
|
|
|
ForceComposeToTarget(target, &aRect);
|
2012-10-04 11:05:24 +04:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2013-06-18 11:58:43 +04:00
|
|
|
bool
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::RecvFlushRendering()
|
2013-06-18 11:58:43 +04:00
|
|
|
{
|
2015-04-30 21:35:13 +03:00
|
|
|
if (mCompositorScheduler->NeedsComposite())
|
|
|
|
{
|
2014-03-10 08:47:12 +04:00
|
|
|
CancelCurrentCompositeTask();
|
2014-02-11 08:58:01 +04:00
|
|
|
ForceComposeToTarget(nullptr);
|
2013-06-18 11:58:43 +04:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-02-24 06:50:09 +03:00
|
|
|
bool
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::RecvForcePresent()
|
2016-02-24 06:50:09 +03:00
|
|
|
{
|
2016-02-25 00:24:26 +03:00
|
|
|
// During the shutdown sequence mLayerManager may be null
|
2016-02-24 06:50:09 +03:00
|
|
|
if (mLayerManager) {
|
|
|
|
mLayerManager->ForcePresent();
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2013-11-21 23:25:16 +04:00
|
|
|
bool
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::RecvNotifyRegionInvalidated(const nsIntRegion& aRegion)
|
2013-11-21 23:25:16 +04:00
|
|
|
{
|
|
|
|
if (mLayerManager) {
|
|
|
|
mLayerManager->AddInvalidRegion(aRegion);
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2015-06-11 18:20:04 +03:00
|
|
|
void
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::Invalidate()
|
2015-06-11 18:20:04 +03:00
|
|
|
{
|
|
|
|
if (mLayerManager && mLayerManager->GetRoot()) {
|
|
|
|
mLayerManager->AddInvalidRegion(
|
2016-02-13 04:24:38 +03:00
|
|
|
mLayerManager->GetRoot()->GetLocalVisibleRegion().ToUnknownRegion().GetBounds());
|
2015-06-11 18:20:04 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-11-27 11:32:19 +04:00
|
|
|
bool
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::RecvStartFrameTimeRecording(const int32_t& aBufferSize, uint32_t* aOutStartIndex)
|
2013-11-27 11:32:19 +04:00
|
|
|
{
|
|
|
|
if (mLayerManager) {
|
|
|
|
*aOutStartIndex = mLayerManager->StartFrameTimeRecording(aBufferSize);
|
|
|
|
} else {
|
|
|
|
*aOutStartIndex = 0;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::RecvStopFrameTimeRecording(const uint32_t& aStartIndex,
|
|
|
|
InfallibleTArray<float>* intervals)
|
2013-11-27 11:32:19 +04:00
|
|
|
{
|
|
|
|
if (mLayerManager) {
|
|
|
|
mLayerManager->StopFrameTimeRecording(aStartIndex, *intervals);
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-03-19 04:38:57 +03:00
|
|
|
bool
|
2016-04-21 11:22:10 +03:00
|
|
|
CompositorBridgeParent::RecvClearVisibleRegions(const uint64_t& aLayersId,
|
|
|
|
const uint32_t& aPresShellId)
|
2016-03-19 04:38:57 +03:00
|
|
|
{
|
2016-04-21 11:22:10 +03:00
|
|
|
ClearVisibleRegions(aLayersId, Some(aPresShellId));
|
2016-03-19 04:38:57 +03:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2016-04-21 11:22:10 +03:00
|
|
|
CompositorBridgeParent::ClearVisibleRegions(const uint64_t& aLayersId,
|
|
|
|
const Maybe<uint32_t>& aPresShellId)
|
2016-03-19 04:38:57 +03:00
|
|
|
{
|
|
|
|
if (mLayerManager) {
|
2016-04-21 11:22:10 +03:00
|
|
|
mLayerManager->ClearVisibleRegions(aLayersId, aPresShellId);
|
2016-03-19 04:38:57 +03:00
|
|
|
|
|
|
|
// We need to recomposite to update the minimap.
|
|
|
|
ScheduleComposition();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-03-19 04:38:57 +03:00
|
|
|
bool
|
2016-04-21 11:22:10 +03:00
|
|
|
CompositorBridgeParent::RecvUpdateVisibleRegion(const VisibilityCounter& aCounter,
|
|
|
|
const ScrollableLayerGuid& aGuid,
|
|
|
|
const CSSIntRegion& aRegion)
|
|
|
|
{
|
|
|
|
UpdateVisibleRegion(aCounter, aGuid, aRegion);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
CompositorBridgeParent::UpdateVisibleRegion(const VisibilityCounter& aCounter,
|
|
|
|
const ScrollableLayerGuid& aGuid,
|
|
|
|
const CSSIntRegion& aRegion)
|
2016-03-19 04:38:57 +03:00
|
|
|
{
|
|
|
|
if (mLayerManager) {
|
2016-04-21 11:22:10 +03:00
|
|
|
mLayerManager->UpdateVisibleRegion(aCounter, aGuid, aRegion);
|
2016-03-19 04:38:57 +03:00
|
|
|
|
|
|
|
// We need to recomposite to update the minimap.
|
|
|
|
ScheduleComposition();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-04-11 14:14:29 +04:00
|
|
|
void
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::ActorDestroy(ActorDestroyReason why)
|
2013-04-11 14:14:29 +04:00
|
|
|
{
|
2016-06-21 18:31:21 +03:00
|
|
|
StopAndClearResources();
|
2013-04-11 14:14:29 +04:00
|
|
|
|
2016-06-21 18:31:21 +03:00
|
|
|
RemoveCompositor(mCompositorID);
|
2015-11-24 04:50:51 +03:00
|
|
|
|
|
|
|
mCompositionManager = nullptr;
|
|
|
|
|
|
|
|
if (mApzcTreeManager) {
|
|
|
|
mApzcTreeManager->ClearTree();
|
|
|
|
mApzcTreeManager = nullptr;
|
|
|
|
}
|
|
|
|
|
2016-06-21 18:31:21 +03:00
|
|
|
{ // scope lock
|
|
|
|
MonitorAutoLock lock(*sIndirectLayerTreesLock);
|
|
|
|
sIndirectLayerTrees.erase(mRootLayerTreeID);
|
|
|
|
}
|
|
|
|
|
2015-11-24 04:50:51 +03:00
|
|
|
// There are chances that the ref count reaches zero on the main thread shortly
|
|
|
|
// after this function returns while some ipdl code still needs to run on
|
|
|
|
// this thread.
|
|
|
|
// We must keep the compositor parent alive untill the code handling message
|
|
|
|
// reception is finished on this thread.
|
|
|
|
mSelfRef = this;
|
2016-05-05 11:45:00 +03:00
|
|
|
MessageLoop::current()->PostTask(NewRunnableMethod(this, &CompositorBridgeParent::DeferredDestroy));
|
2013-04-11 14:14:29 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-02-04 06:35:58 +04:00
|
|
|
void
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::ScheduleRenderOnCompositorThread()
|
2012-02-04 06:35:58 +04:00
|
|
|
{
|
2015-01-27 23:52:44 +03:00
|
|
|
MOZ_ASSERT(CompositorLoop());
|
2016-05-05 11:45:00 +03:00
|
|
|
CompositorLoop()->PostTask(NewRunnableMethod(this, &CompositorBridgeParent::ScheduleComposition));
|
2012-02-04 06:35:58 +04:00
|
|
|
}
|
|
|
|
|
2015-06-11 18:20:04 +03:00
|
|
|
void
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::InvalidateOnCompositorThread()
|
2015-06-11 18:20:04 +03:00
|
|
|
{
|
|
|
|
MOZ_ASSERT(CompositorLoop());
|
2016-05-05 11:45:00 +03:00
|
|
|
CompositorLoop()->PostTask(NewRunnableMethod(this, &CompositorBridgeParent::Invalidate));
|
2015-06-11 18:20:04 +03:00
|
|
|
}
|
|
|
|
|
2012-02-05 22:33:38 +04:00
|
|
|
void
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::PauseComposition()
|
2012-02-05 22:33:38 +04:00
|
|
|
{
|
2016-05-16 09:40:13 +03:00
|
|
|
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread(),
|
2014-06-06 00:42:13 +04:00
|
|
|
"PauseComposition() can only be called on the compositor thread");
|
2012-05-10 06:32:54 +04:00
|
|
|
|
2012-07-18 03:59:45 +04:00
|
|
|
MonitorAutoLock lock(mPauseCompositionMonitor);
|
2012-05-10 06:32:54 +04:00
|
|
|
|
2012-02-06 22:57:06 +04:00
|
|
|
if (!mPaused) {
|
|
|
|
mPaused = true;
|
2012-02-05 22:33:38 +04:00
|
|
|
|
2013-12-09 05:40:58 +04:00
|
|
|
mCompositor->Pause();
|
2015-08-25 08:51:58 +03:00
|
|
|
|
|
|
|
TimeStamp now = TimeStamp::Now();
|
|
|
|
DidComposite(now, now);
|
2012-02-06 22:57:06 +04:00
|
|
|
}
|
2012-05-10 06:32:54 +04:00
|
|
|
|
|
|
|
// if anyone's waiting to make sure that composition really got paused, tell them
|
|
|
|
lock.NotifyAll();
|
2012-02-05 22:33:38 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::ResumeComposition()
|
2012-02-05 22:33:38 +04:00
|
|
|
{
|
2016-05-16 09:40:13 +03:00
|
|
|
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread(),
|
2014-06-06 00:42:13 +04:00
|
|
|
"ResumeComposition() can only be called on the compositor thread");
|
2012-05-29 21:49:03 +04:00
|
|
|
|
2012-07-18 03:59:45 +04:00
|
|
|
MonitorAutoLock lock(mResumeCompositionMonitor);
|
2012-05-29 21:49:03 +04:00
|
|
|
|
2013-12-09 05:40:58 +04:00
|
|
|
if (!mCompositor->Resume()) {
|
2012-02-05 22:33:38 +04:00
|
|
|
#ifdef MOZ_WIDGET_ANDROID
|
2013-01-10 20:21:10 +04:00
|
|
|
// We can't get a surface. This could be because the activity changed between
|
|
|
|
// the time resume was scheduled and now.
|
2016-03-22 21:08:38 +03:00
|
|
|
__android_log_print(ANDROID_LOG_INFO, "CompositorBridgeParent", "Unable to renew compositor surface; remaining in paused state");
|
Bug 825928: Land layers refactoring. r=jrmuizel,bas,nical,mattwoodrow,roc,nrc,benwa,bjacob,jgilbert,kchen CLOSED TREE
Please contact Bas Schouten <bschouten@mozilla.com>, Nicolas Silva <nsilva@mozilla.com> or Nicholas Cameron <ncameron@mozilla.com> with general questions. Below is a rough list of authors to contact with specific questions.
Authors:
gfx/layers/Compositor.* gfx/layers/Effects.h - Compositor Interface - bas,nrc,nical
gfx/layers/d3d* - D3D9/D3D10 - bas
gfx/layers/ThebesLayer* - ThebesLayers - nrc,bas
gfx/layers/composite/* - CompositeLayers - nrc,nical
gfx/layers/client/* - Client - nrc,nical,bas
gfx/layers/*Image* - nical
gfx/layers/ipc ipc - IPC - nical
gfx/layers/opengl - CompositorOGL - nrc,nical
gfx/2d - bas,nrc
gfx/gl - GLContext - bjacob
dom/* layout/* - DOM - mattwoodrow
2013-04-10 13:20:52 +04:00
|
|
|
#endif
|
2013-01-10 20:21:10 +04:00
|
|
|
lock.NotifyAll();
|
|
|
|
return;
|
|
|
|
}
|
2012-05-29 21:49:03 +04:00
|
|
|
|
2013-01-10 20:21:10 +04:00
|
|
|
mPaused = false;
|
Bug 825928: Land layers refactoring. r=jrmuizel,bas,nical,mattwoodrow,roc,nrc,benwa,bjacob,jgilbert,kchen CLOSED TREE
Please contact Bas Schouten <bschouten@mozilla.com>, Nicolas Silva <nsilva@mozilla.com> or Nicholas Cameron <ncameron@mozilla.com> with general questions. Below is a rough list of authors to contact with specific questions.
Authors:
gfx/layers/Compositor.* gfx/layers/Effects.h - Compositor Interface - bas,nrc,nical
gfx/layers/d3d* - D3D9/D3D10 - bas
gfx/layers/ThebesLayer* - ThebesLayers - nrc,bas
gfx/layers/composite/* - CompositeLayers - nrc,nical
gfx/layers/client/* - Client - nrc,nical,bas
gfx/layers/*Image* - nical
gfx/layers/ipc ipc - IPC - nical
gfx/layers/opengl - CompositorOGL - nrc,nical
gfx/2d - bas,nrc
gfx/gl - GLContext - bjacob
dom/* layout/* - DOM - mattwoodrow
2013-04-10 13:20:52 +04:00
|
|
|
|
2015-04-30 21:35:13 +03:00
|
|
|
mCompositorScheduler->ResumeComposition();
|
2012-06-12 18:24:31 +04:00
|
|
|
|
2012-05-29 21:49:03 +04:00
|
|
|
// if anyone's waiting to make sure that composition really got resumed, tell them
|
|
|
|
lock.NotifyAll();
|
2012-02-05 22:33:38 +04:00
|
|
|
}
|
|
|
|
|
2012-11-22 06:40:57 +04:00
|
|
|
void
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::ForceComposition()
|
2012-11-22 06:40:57 +04:00
|
|
|
{
|
|
|
|
// Cancel the orientation changed state to force composition
|
|
|
|
mForceCompositionTask = nullptr;
|
|
|
|
ScheduleRenderOnCompositorThread();
|
|
|
|
}
|
|
|
|
|
2014-03-10 08:47:12 +04:00
|
|
|
void
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::CancelCurrentCompositeTask()
|
2014-03-10 08:47:12 +04:00
|
|
|
{
|
2015-04-30 21:35:13 +03:00
|
|
|
mCompositorScheduler->CancelCurrentCompositeTask();
|
2014-03-10 08:47:12 +04:00
|
|
|
}
|
|
|
|
|
2012-05-08 23:40:41 +04:00
|
|
|
void
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::SetEGLSurfaceSize(int width, int height)
|
2012-05-08 23:40:41 +04:00
|
|
|
{
|
2013-04-30 07:16:04 +04:00
|
|
|
NS_ASSERTION(mUseExternalSurfaceSize, "Compositor created without UseExternalSurfaceSize provided");
|
2012-05-08 23:40:41 +04:00
|
|
|
mEGLSurfaceSize.SizeTo(width, height);
|
2013-12-09 05:40:58 +04:00
|
|
|
if (mCompositor) {
|
|
|
|
mCompositor->SetDestinationSurfaceSize(gfx::IntSize(mEGLSurfaceSize.width, mEGLSurfaceSize.height));
|
2012-05-08 23:40:41 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-04-20 19:46:30 +04:00
|
|
|
void
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::ResumeCompositionAndResize(int width, int height)
|
2012-04-20 19:46:30 +04:00
|
|
|
{
|
2012-05-08 23:40:41 +04:00
|
|
|
SetEGLSurfaceSize(width, height);
|
2012-04-20 19:46:30 +04:00
|
|
|
ResumeComposition();
|
|
|
|
}
|
|
|
|
|
2012-05-10 06:32:54 +04:00
|
|
|
/*
|
|
|
|
* This will execute a pause synchronously, waiting to make sure that the compositor
|
|
|
|
* really is paused.
|
|
|
|
*/
|
2012-02-05 22:33:38 +04:00
|
|
|
void
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::SchedulePauseOnCompositorThread()
|
2012-02-05 22:33:38 +04:00
|
|
|
{
|
2012-07-18 03:59:45 +04:00
|
|
|
MonitorAutoLock lock(mPauseCompositionMonitor);
|
2012-05-10 06:32:54 +04:00
|
|
|
|
2015-01-27 23:52:44 +03:00
|
|
|
MOZ_ASSERT(CompositorLoop());
|
2016-05-05 11:45:00 +03:00
|
|
|
CompositorLoop()->PostTask(NewRunnableMethod(this, &CompositorBridgeParent::PauseComposition));
|
2012-05-10 06:32:54 +04:00
|
|
|
|
|
|
|
// Wait until the pause has actually been processed by the compositor thread
|
|
|
|
lock.Wait();
|
2012-02-05 22:33:38 +04:00
|
|
|
}
|
|
|
|
|
2015-04-11 05:14:00 +03:00
|
|
|
bool
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::ScheduleResumeOnCompositorThread()
|
2015-04-11 05:14:00 +03:00
|
|
|
{
|
|
|
|
MonitorAutoLock lock(mResumeCompositionMonitor);
|
|
|
|
|
|
|
|
MOZ_ASSERT(CompositorLoop());
|
2016-05-05 11:45:00 +03:00
|
|
|
CompositorLoop()->PostTask(NewRunnableMethod(this, &CompositorBridgeParent::ResumeComposition));
|
2015-04-11 05:14:00 +03:00
|
|
|
|
|
|
|
// Wait until the resume has actually been processed by the compositor thread
|
|
|
|
lock.Wait();
|
|
|
|
|
|
|
|
return !mPaused;
|
|
|
|
}
|
|
|
|
|
2013-01-10 20:21:10 +04:00
|
|
|
bool
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::ScheduleResumeOnCompositorThread(int width, int height)
|
2012-02-05 22:33:38 +04:00
|
|
|
{
|
2012-07-18 03:59:45 +04:00
|
|
|
MonitorAutoLock lock(mResumeCompositionMonitor);
|
2012-05-29 21:49:03 +04:00
|
|
|
|
2015-01-27 23:52:44 +03:00
|
|
|
MOZ_ASSERT(CompositorLoop());
|
2016-05-05 11:45:00 +03:00
|
|
|
CompositorLoop()->PostTask(NewRunnableMethod
|
|
|
|
<int, int>(this,
|
|
|
|
&CompositorBridgeParent::ResumeCompositionAndResize,
|
|
|
|
width, height));
|
2012-05-29 21:49:03 +04:00
|
|
|
|
|
|
|
// Wait until the resume has actually been processed by the compositor thread
|
|
|
|
lock.Wait();
|
2013-01-10 20:21:10 +04:00
|
|
|
|
|
|
|
return !mPaused;
|
2012-02-05 22:33:38 +04:00
|
|
|
}
|
|
|
|
|
2012-04-24 17:22:36 +04:00
|
|
|
void
|
2016-04-28 03:06:05 +03:00
|
|
|
CompositorBridgeParent::ScheduleTask(already_AddRefed<CancelableRunnable> task, int time)
|
2012-04-24 17:22:36 +04:00
|
|
|
{
|
2012-05-24 21:34:20 +04:00
|
|
|
if (time == 0) {
|
2016-04-28 03:06:05 +03:00
|
|
|
MessageLoop::current()->PostTask(Move(task));
|
2012-04-24 17:22:36 +04:00
|
|
|
} else {
|
2016-04-28 03:06:05 +03:00
|
|
|
MessageLoop::current()->PostDelayedTask(Move(task), time);
|
2012-04-24 17:22:36 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-16 18:46:13 +03:00
|
|
|
void
|
|
|
|
CompositorBridgeParent::UpdatePaintTime(LayerTransactionParent* aLayerTree,
|
|
|
|
const TimeDuration& aPaintTime)
|
|
|
|
{
|
|
|
|
// We get a lot of paint timings for things with empty transactions.
|
|
|
|
if (!mLayerManager || aPaintTime.ToMilliseconds() < 1.0) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
mLayerManager->SetPaintTime(aPaintTime);
|
|
|
|
}
|
|
|
|
|
2012-08-07 06:41:29 +04:00
|
|
|
void
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::NotifyShadowTreeTransaction(uint64_t aId, bool aIsFirstPaint,
|
2014-05-31 02:52:43 +04:00
|
|
|
bool aScheduleComposite, uint32_t aPaintSequenceNumber,
|
2016-05-16 21:53:44 +03:00
|
|
|
bool aIsRepeatTransaction, bool aHitTestUpdate)
|
2012-08-07 06:41:29 +04:00
|
|
|
{
|
2016-07-18 11:54:02 +03:00
|
|
|
if (!aIsRepeatTransaction &&
|
2013-08-04 11:46:17 +04:00
|
|
|
mLayerManager &&
|
|
|
|
mLayerManager->GetRoot()) {
|
2016-07-18 11:54:02 +03:00
|
|
|
// Process plugin data here to give time for them to update before the next
|
|
|
|
// composition.
|
|
|
|
bool pluginsUpdatedFlag = true;
|
|
|
|
AutoResolveRefLayers resolve(mCompositionManager, this, nullptr,
|
|
|
|
&pluginsUpdatedFlag);
|
|
|
|
|
|
|
|
#if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
|
|
|
|
// If plugins haven't been updated, stop waiting.
|
|
|
|
if (!pluginsUpdatedFlag) {
|
|
|
|
mWaitForPluginsUntil = TimeStamp();
|
|
|
|
mHaveBlockedForPlugins = false;
|
|
|
|
}
|
|
|
|
#endif
|
2016-05-16 21:53:44 +03:00
|
|
|
|
2016-07-18 11:54:02 +03:00
|
|
|
if (mApzcTreeManager && aHitTestUpdate) {
|
2016-05-16 21:53:44 +03:00
|
|
|
mApzcTreeManager->UpdateHitTestingTree(this, mLayerManager->GetRoot(),
|
|
|
|
aIsFirstPaint, aId, aPaintSequenceNumber);
|
|
|
|
}
|
2013-07-30 22:03:40 +04:00
|
|
|
|
2014-02-11 02:14:11 +04:00
|
|
|
mLayerManager->NotifyShadowTreeTransaction();
|
2012-08-07 06:41:29 +04:00
|
|
|
}
|
2013-12-16 09:38:42 +04:00
|
|
|
if (aScheduleComposite) {
|
|
|
|
ScheduleComposition();
|
|
|
|
}
|
2012-08-07 06:41:29 +04:00
|
|
|
}
|
|
|
|
|
2011-12-19 22:17:29 +04:00
|
|
|
void
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::ScheduleComposition()
|
2014-10-22 02:40:54 +04:00
|
|
|
{
|
2016-05-16 09:40:13 +03:00
|
|
|
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
2015-01-22 03:13:15 +03:00
|
|
|
if (mPaused) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-04-30 21:35:13 +03:00
|
|
|
mCompositorScheduler->ScheduleComposition();
|
2014-02-11 08:58:01 +04:00
|
|
|
}
|
|
|
|
|
2014-10-20 08:04:39 +04:00
|
|
|
// Go down the composite layer tree, setting properties to match their
|
|
|
|
// content-side counterparts.
|
2015-01-15 01:24:09 +03:00
|
|
|
/* static */ void
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::SetShadowProperties(Layer* aLayer)
|
2014-10-20 08:04:39 +04:00
|
|
|
{
|
2016-03-10 12:20:40 +03:00
|
|
|
ForEachNode<ForwardIterator>(
|
|
|
|
aLayer,
|
|
|
|
[] (Layer *layer)
|
|
|
|
{
|
|
|
|
if (Layer* maskLayer = layer->GetMaskLayer()) {
|
|
|
|
SetShadowProperties(maskLayer);
|
|
|
|
}
|
|
|
|
for (size_t i = 0; i < layer->GetAncestorMaskLayerCount(); i++) {
|
|
|
|
SetShadowProperties(layer->GetAncestorMaskLayerAt(i));
|
|
|
|
}
|
|
|
|
|
|
|
|
// FIXME: Bug 717688 -- Do these updates in LayerTransactionParent::RecvUpdate.
|
|
|
|
LayerComposite* layerComposite = layer->AsLayerComposite();
|
|
|
|
// Set the layerComposite's base transform to the layer's base transform.
|
|
|
|
layerComposite->SetShadowBaseTransform(layer->GetBaseTransform());
|
|
|
|
layerComposite->SetShadowTransformSetByAnimation(false);
|
|
|
|
layerComposite->SetShadowVisibleRegion(layer->GetVisibleRegion());
|
|
|
|
layerComposite->SetShadowClipRect(layer->GetClipRect());
|
|
|
|
layerComposite->SetShadowOpacity(layer->GetOpacity());
|
|
|
|
}
|
|
|
|
);
|
2014-10-20 08:04:39 +04:00
|
|
|
}
|
|
|
|
|
2014-02-11 08:58:01 +04:00
|
|
|
void
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::CompositeToTarget(DrawTarget* aTarget, const gfx::IntRect* aRect)
|
2011-12-19 22:17:29 +04:00
|
|
|
{
|
2013-11-05 02:04:51 +04:00
|
|
|
profiler_tracing("Paint", "Composite", TRACING_INTERVAL_START);
|
2016-03-22 21:08:38 +03:00
|
|
|
PROFILER_LABEL("CompositorBridgeParent", "Composite",
|
2014-05-24 01:12:29 +04:00
|
|
|
js::ProfileEntry::Category::GRAPHICS);
|
|
|
|
|
2016-05-16 09:40:13 +03:00
|
|
|
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread(),
|
2014-06-06 00:42:13 +04:00
|
|
|
"Composite can only be called on the compositor thread");
|
2014-12-11 05:15:48 +03:00
|
|
|
TimeStamp start = TimeStamp::Now();
|
2014-03-04 23:41:24 +04:00
|
|
|
|
|
|
|
#ifdef COMPOSITOR_PERFORMANCE_WARNING
|
2015-04-30 21:35:13 +03:00
|
|
|
TimeDuration scheduleDelta = TimeStamp::Now() - mCompositorScheduler->GetExpectedComposeStartTime();
|
2014-03-04 23:41:24 +04:00
|
|
|
if (scheduleDelta > TimeDuration::FromMilliseconds(2) ||
|
|
|
|
scheduleDelta < TimeDuration::FromMilliseconds(-2)) {
|
|
|
|
printf_stderr("Compositor: Compose starting off schedule by %4.1f ms\n",
|
|
|
|
scheduleDelta.ToMilliseconds());
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2012-10-04 11:05:24 +04:00
|
|
|
if (!CanComposite()) {
|
2015-09-09 02:14:51 +03:00
|
|
|
TimeStamp end = TimeStamp::Now();
|
|
|
|
DidComposite(start, end);
|
2011-12-16 00:07:25 +04:00
|
|
|
return;
|
2011-12-19 22:17:29 +04:00
|
|
|
}
|
2011-12-16 00:07:25 +04:00
|
|
|
|
2016-07-18 11:54:02 +03:00
|
|
|
#if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
|
|
|
|
if (!mWaitForPluginsUntil.IsNull() &&
|
|
|
|
mWaitForPluginsUntil > start) {
|
|
|
|
mHaveBlockedForPlugins = true;
|
|
|
|
ScheduleComposition();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2015-10-06 22:23:24 +03:00
|
|
|
/*
|
|
|
|
* AutoResolveRefLayers handles two tasks related to Windows and Linux
|
|
|
|
* plugin window management:
|
|
|
|
* 1) calculating if we have remote content in the view. If we do not have
|
2016-03-22 21:08:38 +03:00
|
|
|
* remote content, all plugin windows for this CompositorBridgeParent (window)
|
2015-10-06 22:23:24 +03:00
|
|
|
* can be hidden since we do not support plugins in chrome when running
|
|
|
|
* under e10s.
|
|
|
|
* 2) Updating plugin position, size, and clip. We do this here while the
|
|
|
|
* remote layer tree is hooked up to to chrome layer tree. This is needed
|
|
|
|
* since plugin clipping can depend on chrome (for example, due to tab modal
|
|
|
|
* prompts). Updates in step 2 are applied via an async ipc message sent
|
|
|
|
* to the main thread.
|
|
|
|
*/
|
2016-03-24 17:40:26 +03:00
|
|
|
bool hasRemoteContent = false;
|
|
|
|
bool updatePluginsFlag = true;
|
|
|
|
AutoResolveRefLayers resolve(mCompositionManager, this,
|
|
|
|
&hasRemoteContent,
|
|
|
|
&updatePluginsFlag);
|
2015-10-06 22:23:24 +03:00
|
|
|
|
2016-03-24 17:40:26 +03:00
|
|
|
#if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
|
2015-10-06 22:23:24 +03:00
|
|
|
// We do not support plugins in local content. When switching tabs
|
|
|
|
// to local pages, hide every plugin associated with the window.
|
2016-08-04 21:33:44 +03:00
|
|
|
if (!hasRemoteContent && gfxVars::BrowserTabsRemoteAutostart() &&
|
2015-10-06 22:23:24 +03:00
|
|
|
mCachedPluginData.Length()) {
|
2016-07-01 11:15:16 +03:00
|
|
|
Unused << SendHideAllPlugins(GetWidget()->GetWidgetKey());
|
2015-10-06 22:23:24 +03:00
|
|
|
mCachedPluginData.Clear();
|
2015-10-06 22:23:24 +03:00
|
|
|
}
|
|
|
|
#endif
|
2014-02-11 08:00:16 +04:00
|
|
|
|
|
|
|
if (aTarget) {
|
2014-05-28 05:21:32 +04:00
|
|
|
mLayerManager->BeginTransactionWithDrawTarget(aTarget, *aRect);
|
2014-02-11 08:00:16 +04:00
|
|
|
} else {
|
|
|
|
mLayerManager->BeginTransaction();
|
|
|
|
}
|
|
|
|
|
2014-10-20 08:04:39 +04:00
|
|
|
SetShadowProperties(mLayerManager->GetRoot());
|
|
|
|
|
2012-11-22 06:40:57 +04:00
|
|
|
if (mForceCompositionTask && !mOverrideComposeReadiness) {
|
2013-04-28 10:46:30 +04:00
|
|
|
if (mCompositionManager->ReadyForCompose()) {
|
2012-11-22 06:40:57 +04:00
|
|
|
mForceCompositionTask->Cancel();
|
|
|
|
mForceCompositionTask = nullptr;
|
2013-04-28 10:46:30 +04:00
|
|
|
} else {
|
|
|
|
return;
|
2012-11-22 06:40:57 +04:00
|
|
|
}
|
|
|
|
}
|
2012-07-18 03:59:45 +04:00
|
|
|
|
2014-09-30 18:07:05 +04:00
|
|
|
mCompositionManager->ComputeRotation();
|
|
|
|
|
2015-04-30 21:35:13 +03:00
|
|
|
TimeStamp time = mIsTesting ? mTestTime : mCompositorScheduler->GetLastComposeTime();
|
2016-07-26 11:57:11 +03:00
|
|
|
bool requestNextFrame = mCompositionManager->TransformShadowTree(time, mVsyncRate);
|
2012-07-20 10:48:27 +04:00
|
|
|
if (requestNextFrame) {
|
|
|
|
ScheduleComposition();
|
2016-07-18 11:54:02 +03:00
|
|
|
#if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
|
|
|
|
// If we have visible windowed plugins then we need to wait for content (and
|
|
|
|
// then the plugins) to have been updated by the active animation.
|
|
|
|
if (!mPluginWindowsHidden && mCachedPluginData.Length()) {
|
|
|
|
mWaitForPluginsUntil = mCompositorScheduler->GetLastComposeTime()
|
|
|
|
+ (GetGlobalVsyncRate() * 2);
|
|
|
|
}
|
|
|
|
#endif
|
2012-07-20 10:48:27 +04:00
|
|
|
}
|
2012-02-10 07:47:50 +04:00
|
|
|
|
2013-04-28 10:46:30 +04:00
|
|
|
RenderTraceLayers(mLayerManager->GetRoot(), "0000");
|
|
|
|
|
Bug 825928: Land layers refactoring. r=jrmuizel,bas,nical,mattwoodrow,roc,nrc,benwa,bjacob,jgilbert,kchen CLOSED TREE
Please contact Bas Schouten <bschouten@mozilla.com>, Nicolas Silva <nsilva@mozilla.com> or Nicholas Cameron <ncameron@mozilla.com> with general questions. Below is a rough list of authors to contact with specific questions.
Authors:
gfx/layers/Compositor.* gfx/layers/Effects.h - Compositor Interface - bas,nrc,nical
gfx/layers/d3d* - D3D9/D3D10 - bas
gfx/layers/ThebesLayer* - ThebesLayers - nrc,bas
gfx/layers/composite/* - CompositeLayers - nrc,nical
gfx/layers/client/* - Client - nrc,nical,bas
gfx/layers/*Image* - nical
gfx/layers/ipc ipc - IPC - nical
gfx/layers/opengl - CompositorOGL - nrc,nical
gfx/2d - bas,nrc
gfx/gl - GLContext - bjacob
dom/* layout/* - DOM - mattwoodrow
2013-04-10 13:20:52 +04:00
|
|
|
#ifdef MOZ_DUMP_PAINTING
|
2015-02-04 01:18:44 +03:00
|
|
|
if (gfxPrefs::DumpHostLayers()) {
|
2013-11-24 02:44:18 +04:00
|
|
|
printf_stderr("Painting --- compositing layer tree:\n");
|
2016-03-17 23:18:10 +03:00
|
|
|
mLayerManager->Dump(/* aSorted = */ true);
|
2012-07-24 23:01:09 +04:00
|
|
|
}
|
Bug 825928: Land layers refactoring. r=jrmuizel,bas,nical,mattwoodrow,roc,nrc,benwa,bjacob,jgilbert,kchen CLOSED TREE
Please contact Bas Schouten <bschouten@mozilla.com>, Nicolas Silva <nsilva@mozilla.com> or Nicholas Cameron <ncameron@mozilla.com> with general questions. Below is a rough list of authors to contact with specific questions.
Authors:
gfx/layers/Compositor.* gfx/layers/Effects.h - Compositor Interface - bas,nrc,nical
gfx/layers/d3d* - D3D9/D3D10 - bas
gfx/layers/ThebesLayer* - ThebesLayers - nrc,bas
gfx/layers/composite/* - CompositeLayers - nrc,nical
gfx/layers/client/* - Client - nrc,nical,bas
gfx/layers/*Image* - nical
gfx/layers/ipc ipc - IPC - nical
gfx/layers/opengl - CompositorOGL - nrc,nical
gfx/2d - bas,nrc
gfx/gl - GLContext - bjacob
dom/* layout/* - DOM - mattwoodrow
2013-04-10 13:20:52 +04:00
|
|
|
#endif
|
2013-12-04 00:04:47 +04:00
|
|
|
mLayerManager->SetDebugOverlayWantsNextFrame(false);
|
2015-07-07 06:38:38 +03:00
|
|
|
mLayerManager->EndTransaction(time);
|
2012-02-11 03:06:17 +04:00
|
|
|
|
2015-09-09 02:14:51 +03:00
|
|
|
if (!aTarget) {
|
|
|
|
TimeStamp end = TimeStamp::Now();
|
|
|
|
DidComposite(start, end);
|
|
|
|
}
|
|
|
|
|
2015-03-19 09:58:16 +03:00
|
|
|
// We're not really taking advantage of the stored composite-again-time here.
|
|
|
|
// We might be able to skip the next few composites altogether. However,
|
|
|
|
// that's a bit complex to implement and we'll get most of the advantage
|
2015-08-01 05:02:51 +03:00
|
|
|
// by skipping compositing when we detect there's nothing invalid. This is why
|
|
|
|
// we do "composite until" rather than "composite again at".
|
|
|
|
if (!mCompositor->GetCompositeUntilTime().IsNull() ||
|
2015-03-19 09:58:16 +03:00
|
|
|
mLayerManager->DebugOverlayWantsNextFrame()) {
|
2013-12-03 19:49:46 +04:00
|
|
|
ScheduleComposition();
|
|
|
|
}
|
|
|
|
|
2012-02-11 03:06:17 +04:00
|
|
|
#ifdef COMPOSITOR_PERFORMANCE_WARNING
|
2015-04-30 21:35:13 +03:00
|
|
|
TimeDuration executionTime = TimeStamp::Now() - mCompositorScheduler->GetLastComposeTime();
|
2014-03-04 23:41:24 +04:00
|
|
|
TimeDuration frameBudget = TimeDuration::FromMilliseconds(15);
|
|
|
|
int32_t frameRate = CalculateCompositionFrameRate();
|
|
|
|
if (frameRate > 0) {
|
|
|
|
frameBudget = TimeDuration::FromSeconds(1.0 / frameRate);
|
|
|
|
}
|
|
|
|
if (executionTime > frameBudget) {
|
|
|
|
printf_stderr("Compositor: Composite execution took %4.1f ms\n",
|
|
|
|
executionTime.ToMilliseconds());
|
2012-02-11 03:06:17 +04:00
|
|
|
}
|
|
|
|
#endif
|
2014-01-30 03:26:38 +04:00
|
|
|
|
|
|
|
// 0 -> Full-tilt composite
|
2014-03-25 20:54:39 +04:00
|
|
|
if (gfxPrefs::LayersCompositionFrameRate() == 0
|
2014-04-26 06:34:06 +04:00
|
|
|
|| mLayerManager->GetCompositor()->GetDiagnosticTypes() & DiagnosticTypes::FLASH_BORDERS) {
|
2014-01-30 03:26:38 +04:00
|
|
|
// Special full-tilt composite mode for performance testing
|
|
|
|
ScheduleComposition();
|
|
|
|
}
|
2015-07-07 06:38:38 +03:00
|
|
|
mCompositor->SetCompositionTime(TimeStamp());
|
2014-01-30 03:26:38 +04:00
|
|
|
|
2014-12-11 05:15:48 +03:00
|
|
|
mozilla::Telemetry::AccumulateTimeDelta(mozilla::Telemetry::COMPOSITE_TIME, start);
|
2013-09-27 20:08:45 +04:00
|
|
|
profiler_tracing("Paint", "Composite", TRACING_INTERVAL_END);
|
2011-12-16 00:07:19 +04:00
|
|
|
}
|
|
|
|
|
2015-10-06 22:23:24 +03:00
|
|
|
bool
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::RecvRemotePluginsReady()
|
2015-10-06 22:23:24 +03:00
|
|
|
{
|
2016-01-12 20:05:58 +03:00
|
|
|
#if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
|
2016-07-18 11:54:02 +03:00
|
|
|
mWaitForPluginsUntil = TimeStamp();
|
|
|
|
if (mHaveBlockedForPlugins) {
|
|
|
|
mHaveBlockedForPlugins = false;
|
|
|
|
ForceComposeToTarget(nullptr);
|
|
|
|
} else {
|
|
|
|
ScheduleComposition();
|
|
|
|
}
|
2015-10-06 22:23:24 +03:00
|
|
|
return true;
|
|
|
|
#else
|
2016-03-22 21:08:38 +03:00
|
|
|
NS_NOTREACHED("CompositorBridgeParent::RecvRemotePluginsReady calls "
|
2015-10-06 22:23:24 +03:00
|
|
|
"unexpected on this platform.");
|
|
|
|
return false;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2012-10-04 11:05:24 +04:00
|
|
|
void
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::ForceComposeToTarget(DrawTarget* aTarget, const gfx::IntRect* aRect)
|
2012-10-04 11:05:24 +04:00
|
|
|
{
|
2016-03-22 21:08:38 +03:00
|
|
|
PROFILER_LABEL("CompositorBridgeParent", "ForceComposeToTarget",
|
2014-05-24 01:12:29 +04:00
|
|
|
js::ProfileEntry::Category::GRAPHICS);
|
|
|
|
|
2012-11-22 06:40:57 +04:00
|
|
|
AutoRestore<bool> override(mOverrideComposeReadiness);
|
|
|
|
mOverrideComposeReadiness = true;
|
2015-04-30 21:35:13 +03:00
|
|
|
mCompositorScheduler->ForceComposeToTarget(aTarget, aRect);
|
2012-10-04 11:05:24 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::CanComposite()
|
2012-10-04 11:05:24 +04:00
|
|
|
{
|
2014-06-06 17:51:27 +04:00
|
|
|
return mLayerManager &&
|
|
|
|
mLayerManager->GetRoot() &&
|
|
|
|
!mPaused;
|
2012-10-04 11:05:24 +04:00
|
|
|
}
|
|
|
|
|
Bug 825928: Land layers refactoring. r=jrmuizel,bas,nical,mattwoodrow,roc,nrc,benwa,bjacob,jgilbert,kchen CLOSED TREE
Please contact Bas Schouten <bschouten@mozilla.com>, Nicolas Silva <nsilva@mozilla.com> or Nicholas Cameron <ncameron@mozilla.com> with general questions. Below is a rough list of authors to contact with specific questions.
Authors:
gfx/layers/Compositor.* gfx/layers/Effects.h - Compositor Interface - bas,nrc,nical
gfx/layers/d3d* - D3D9/D3D10 - bas
gfx/layers/ThebesLayer* - ThebesLayers - nrc,bas
gfx/layers/composite/* - CompositeLayers - nrc,nical
gfx/layers/client/* - Client - nrc,nical,bas
gfx/layers/*Image* - nical
gfx/layers/ipc ipc - IPC - nical
gfx/layers/opengl - CompositorOGL - nrc,nical
gfx/2d - bas,nrc
gfx/gl - GLContext - bjacob
dom/* layout/* - DOM - mattwoodrow
2013-04-10 13:20:52 +04:00
|
|
|
void
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::ScheduleRotationOnCompositorThread(const TargetConfig& aTargetConfig,
|
2014-04-28 06:22:00 +04:00
|
|
|
bool aIsFirstPaint)
|
Bug 825928: Land layers refactoring. r=jrmuizel,bas,nical,mattwoodrow,roc,nrc,benwa,bjacob,jgilbert,kchen CLOSED TREE
Please contact Bas Schouten <bschouten@mozilla.com>, Nicolas Silva <nsilva@mozilla.com> or Nicholas Cameron <ncameron@mozilla.com> with general questions. Below is a rough list of authors to contact with specific questions.
Authors:
gfx/layers/Compositor.* gfx/layers/Effects.h - Compositor Interface - bas,nrc,nical
gfx/layers/d3d* - D3D9/D3D10 - bas
gfx/layers/ThebesLayer* - ThebesLayers - nrc,bas
gfx/layers/composite/* - CompositeLayers - nrc,nical
gfx/layers/client/* - Client - nrc,nical,bas
gfx/layers/*Image* - nical
gfx/layers/ipc ipc - IPC - nical
gfx/layers/opengl - CompositorOGL - nrc,nical
gfx/2d - bas,nrc
gfx/gl - GLContext - bjacob
dom/* layout/* - DOM - mattwoodrow
2013-04-10 13:20:52 +04:00
|
|
|
{
|
2016-05-16 09:40:13 +03:00
|
|
|
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
2014-04-28 06:22:00 +04:00
|
|
|
|
2013-12-16 09:38:42 +04:00
|
|
|
if (!aIsFirstPaint &&
|
2013-04-28 10:46:30 +04:00
|
|
|
!mCompositionManager->IsFirstPaint() &&
|
|
|
|
mCompositionManager->RequiresReorientation(aTargetConfig.orientation())) {
|
2013-07-20 12:48:55 +04:00
|
|
|
if (mForceCompositionTask != nullptr) {
|
Bug 825928: Land layers refactoring. r=jrmuizel,bas,nical,mattwoodrow,roc,nrc,benwa,bjacob,jgilbert,kchen CLOSED TREE
Please contact Bas Schouten <bschouten@mozilla.com>, Nicolas Silva <nsilva@mozilla.com> or Nicholas Cameron <ncameron@mozilla.com> with general questions. Below is a rough list of authors to contact with specific questions.
Authors:
gfx/layers/Compositor.* gfx/layers/Effects.h - Compositor Interface - bas,nrc,nical
gfx/layers/d3d* - D3D9/D3D10 - bas
gfx/layers/ThebesLayer* - ThebesLayers - nrc,bas
gfx/layers/composite/* - CompositeLayers - nrc,nical
gfx/layers/client/* - Client - nrc,nical,bas
gfx/layers/*Image* - nical
gfx/layers/ipc ipc - IPC - nical
gfx/layers/opengl - CompositorOGL - nrc,nical
gfx/2d - bas,nrc
gfx/gl - GLContext - bjacob
dom/* layout/* - DOM - mattwoodrow
2013-04-10 13:20:52 +04:00
|
|
|
mForceCompositionTask->Cancel();
|
|
|
|
}
|
2016-05-05 11:44:59 +03:00
|
|
|
RefPtr<CancelableRunnable> task =
|
2016-05-05 11:45:00 +03:00
|
|
|
NewCancelableRunnableMethod(this, &CompositorBridgeParent::ForceComposition);
|
2016-04-28 03:06:05 +03:00
|
|
|
mForceCompositionTask = task;
|
|
|
|
ScheduleTask(task.forget(), gfxPrefs::OrientationSyncMillis());
|
Bug 825928: Land layers refactoring. r=jrmuizel,bas,nical,mattwoodrow,roc,nrc,benwa,bjacob,jgilbert,kchen CLOSED TREE
Please contact Bas Schouten <bschouten@mozilla.com>, Nicolas Silva <nsilva@mozilla.com> or Nicholas Cameron <ncameron@mozilla.com> with general questions. Below is a rough list of authors to contact with specific questions.
Authors:
gfx/layers/Compositor.* gfx/layers/Effects.h - Compositor Interface - bas,nrc,nical
gfx/layers/d3d* - D3D9/D3D10 - bas
gfx/layers/ThebesLayer* - ThebesLayers - nrc,bas
gfx/layers/composite/* - CompositeLayers - nrc,nical
gfx/layers/client/* - Client - nrc,nical,bas
gfx/layers/*Image* - nical
gfx/layers/ipc ipc - IPC - nical
gfx/layers/opengl - CompositorOGL - nrc,nical
gfx/2d - bas,nrc
gfx/gl - GLContext - bjacob
dom/* layout/* - DOM - mattwoodrow
2013-04-10 13:20:52 +04:00
|
|
|
}
|
2014-04-28 06:22:00 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::ShadowLayersUpdated(LayerTransactionParent* aLayerTree,
|
|
|
|
const uint64_t& aTransactionId,
|
|
|
|
const TargetConfig& aTargetConfig,
|
|
|
|
const InfallibleTArray<PluginWindowData>& aUnused,
|
|
|
|
bool aIsFirstPaint,
|
|
|
|
bool aScheduleComposite,
|
|
|
|
uint32_t aPaintSequenceNumber,
|
|
|
|
bool aIsRepeatTransaction,
|
2016-05-16 21:53:44 +03:00
|
|
|
int32_t aPaintSyncId,
|
|
|
|
bool aHitTestUpdate)
|
2014-04-28 06:22:00 +04:00
|
|
|
{
|
|
|
|
ScheduleRotationOnCompositorThread(aTargetConfig, aIsFirstPaint);
|
Bug 825928: Land layers refactoring. r=jrmuizel,bas,nical,mattwoodrow,roc,nrc,benwa,bjacob,jgilbert,kchen CLOSED TREE
Please contact Bas Schouten <bschouten@mozilla.com>, Nicolas Silva <nsilva@mozilla.com> or Nicholas Cameron <ncameron@mozilla.com> with general questions. Below is a rough list of authors to contact with specific questions.
Authors:
gfx/layers/Compositor.* gfx/layers/Effects.h - Compositor Interface - bas,nrc,nical
gfx/layers/d3d* - D3D9/D3D10 - bas
gfx/layers/ThebesLayer* - ThebesLayers - nrc,bas
gfx/layers/composite/* - CompositeLayers - nrc,nical
gfx/layers/client/* - Client - nrc,nical,bas
gfx/layers/*Image* - nical
gfx/layers/ipc ipc - IPC - nical
gfx/layers/opengl - CompositorOGL - nrc,nical
gfx/2d - bas,nrc
gfx/gl - GLContext - bjacob
dom/* layout/* - DOM - mattwoodrow
2013-04-10 13:20:52 +04:00
|
|
|
|
|
|
|
// Instruct the LayerManager to update its render bounds now. Since all the orientation
|
|
|
|
// change, dimension change would be done at the stage, update the size here is free of
|
|
|
|
// race condition.
|
2014-09-10 23:59:00 +04:00
|
|
|
mLayerManager->UpdateRenderBounds(aTargetConfig.naturalBounds());
|
2014-03-28 07:38:32 +04:00
|
|
|
mLayerManager->SetRegionToClear(aTargetConfig.clearRegion());
|
2015-07-24 17:13:59 +03:00
|
|
|
mLayerManager->GetCompositor()->SetScreenRotation(aTargetConfig.rotation());
|
Bug 825928: Land layers refactoring. r=jrmuizel,bas,nical,mattwoodrow,roc,nrc,benwa,bjacob,jgilbert,kchen CLOSED TREE
Please contact Bas Schouten <bschouten@mozilla.com>, Nicolas Silva <nsilva@mozilla.com> or Nicholas Cameron <ncameron@mozilla.com> with general questions. Below is a rough list of authors to contact with specific questions.
Authors:
gfx/layers/Compositor.* gfx/layers/Effects.h - Compositor Interface - bas,nrc,nical
gfx/layers/d3d* - D3D9/D3D10 - bas
gfx/layers/ThebesLayer* - ThebesLayers - nrc,bas
gfx/layers/composite/* - CompositeLayers - nrc,nical
gfx/layers/client/* - Client - nrc,nical,bas
gfx/layers/*Image* - nical
gfx/layers/ipc ipc - IPC - nical
gfx/layers/opengl - CompositorOGL - nrc,nical
gfx/2d - bas,nrc
gfx/gl - GLContext - bjacob
dom/* layout/* - DOM - mattwoodrow
2013-04-10 13:20:52 +04:00
|
|
|
|
2015-08-18 21:27:20 +03:00
|
|
|
mCompositionManager->Updated(aIsFirstPaint, aTargetConfig, aPaintSyncId);
|
Bug 825928: Land layers refactoring. r=jrmuizel,bas,nical,mattwoodrow,roc,nrc,benwa,bjacob,jgilbert,kchen CLOSED TREE
Please contact Bas Schouten <bschouten@mozilla.com>, Nicolas Silva <nsilva@mozilla.com> or Nicholas Cameron <ncameron@mozilla.com> with general questions. Below is a rough list of authors to contact with specific questions.
Authors:
gfx/layers/Compositor.* gfx/layers/Effects.h - Compositor Interface - bas,nrc,nical
gfx/layers/d3d* - D3D9/D3D10 - bas
gfx/layers/ThebesLayer* - ThebesLayers - nrc,bas
gfx/layers/composite/* - CompositeLayers - nrc,nical
gfx/layers/client/* - Client - nrc,nical,bas
gfx/layers/*Image* - nical
gfx/layers/ipc ipc - IPC - nical
gfx/layers/opengl - CompositorOGL - nrc,nical
gfx/2d - bas,nrc
gfx/gl - GLContext - bjacob
dom/* layout/* - DOM - mattwoodrow
2013-04-10 13:20:52 +04:00
|
|
|
Layer* root = aLayerTree->GetRoot();
|
|
|
|
mLayerManager->SetRoot(root);
|
2013-07-30 22:03:40 +04:00
|
|
|
|
2016-05-16 21:53:44 +03:00
|
|
|
if (mApzcTreeManager && !aIsRepeatTransaction && aHitTestUpdate) {
|
2013-07-30 22:03:40 +04:00
|
|
|
AutoResolveRefLayers resolve(mCompositionManager);
|
2016-05-16 21:53:44 +03:00
|
|
|
|
2015-01-08 17:40:01 +03:00
|
|
|
mApzcTreeManager->UpdateHitTestingTree(this, root, aIsFirstPaint,
|
2014-05-07 01:26:13 +04:00
|
|
|
mRootLayerTreeID, aPaintSequenceNumber);
|
2013-07-30 22:03:40 +04:00
|
|
|
}
|
2014-05-29 01:43:39 +04:00
|
|
|
|
2015-07-16 21:18:55 +03:00
|
|
|
// The transaction ID might get reset to 1 if the page gets reloaded, see
|
|
|
|
// https://bugzilla.mozilla.org/show_bug.cgi?id=1145295#c41
|
|
|
|
// Otherwise, it should be continually increasing.
|
|
|
|
MOZ_ASSERT(aTransactionId == 1 || aTransactionId > mPendingTransaction);
|
2014-05-29 01:42:14 +04:00
|
|
|
mPendingTransaction = aTransactionId;
|
2013-07-30 22:03:40 +04:00
|
|
|
|
2014-10-23 00:03:18 +04:00
|
|
|
if (root) {
|
|
|
|
SetShadowProperties(root);
|
|
|
|
}
|
2013-12-16 09:38:42 +04:00
|
|
|
if (aScheduleComposite) {
|
|
|
|
ScheduleComposition();
|
2014-05-29 01:42:16 +04:00
|
|
|
if (mPaused) {
|
2015-08-25 08:51:58 +03:00
|
|
|
TimeStamp now = TimeStamp::Now();
|
|
|
|
DidComposite(now, now);
|
2014-05-29 01:42:16 +04:00
|
|
|
}
|
2013-12-16 09:38:42 +04:00
|
|
|
}
|
2014-02-11 02:14:11 +04:00
|
|
|
mLayerManager->NotifyShadowTreeTransaction();
|
Bug 825928: Land layers refactoring. r=jrmuizel,bas,nical,mattwoodrow,roc,nrc,benwa,bjacob,jgilbert,kchen CLOSED TREE
Please contact Bas Schouten <bschouten@mozilla.com>, Nicolas Silva <nsilva@mozilla.com> or Nicholas Cameron <ncameron@mozilla.com> with general questions. Below is a rough list of authors to contact with specific questions.
Authors:
gfx/layers/Compositor.* gfx/layers/Effects.h - Compositor Interface - bas,nrc,nical
gfx/layers/d3d* - D3D9/D3D10 - bas
gfx/layers/ThebesLayer* - ThebesLayers - nrc,bas
gfx/layers/composite/* - CompositeLayers - nrc,nical
gfx/layers/client/* - Client - nrc,nical,bas
gfx/layers/*Image* - nical
gfx/layers/ipc ipc - IPC - nical
gfx/layers/opengl - CompositorOGL - nrc,nical
gfx/2d - bas,nrc
gfx/gl - GLContext - bjacob
dom/* layout/* - DOM - mattwoodrow
2013-04-10 13:20:52 +04:00
|
|
|
}
|
|
|
|
|
2014-03-03 04:59:58 +04:00
|
|
|
void
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::ForceComposite(LayerTransactionParent* aLayerTree)
|
2014-03-03 04:59:58 +04:00
|
|
|
{
|
|
|
|
ScheduleComposition();
|
|
|
|
}
|
|
|
|
|
2014-03-22 01:59:57 +04:00
|
|
|
bool
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::SetTestSampleTime(LayerTransactionParent* aLayerTree,
|
|
|
|
const TimeStamp& aTime)
|
2014-03-22 01:59:57 +04:00
|
|
|
{
|
|
|
|
if (aTime.IsNull()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
mIsTesting = true;
|
|
|
|
mTestTime = aTime;
|
|
|
|
|
2015-04-30 21:35:13 +03:00
|
|
|
bool testComposite = mCompositionManager &&
|
|
|
|
mCompositorScheduler->NeedsComposite();
|
2014-10-22 02:40:54 +04:00
|
|
|
|
2014-03-22 01:59:57 +04:00
|
|
|
// Update but only if we were already scheduled to animate
|
2014-10-22 02:40:54 +04:00
|
|
|
if (testComposite) {
|
2014-03-22 01:59:57 +04:00
|
|
|
AutoResolveRefLayers resolve(mCompositionManager);
|
2016-07-26 11:57:11 +03:00
|
|
|
bool requestNextFrame = mCompositionManager->TransformShadowTree(aTime, mVsyncRate);
|
2014-03-22 01:59:57 +04:00
|
|
|
if (!requestNextFrame) {
|
|
|
|
CancelCurrentCompositeTask();
|
2014-05-29 01:42:16 +04:00
|
|
|
// Pretend we composited in case someone is wating for this event.
|
2015-08-25 08:51:58 +03:00
|
|
|
TimeStamp now = TimeStamp::Now();
|
|
|
|
DidComposite(now, now);
|
2014-03-22 01:59:57 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::LeaveTestMode(LayerTransactionParent* aLayerTree)
|
2014-03-22 01:59:57 +04:00
|
|
|
{
|
|
|
|
mIsTesting = false;
|
|
|
|
}
|
|
|
|
|
Bug 1113425 part 2 - Apply async properties when querying the animated transform; r=mattwoodrow
In order to test off-main thread animations, we have a method that will return
the animated transform value set on a shadow layer. This method will return null
if the transform was not set by animation.
However, in some situations we temporarily clear the animation transform. For
example, when we synchronize a composite layer with its content layer, we reset
the animation transform. Then, on the next composite, we will recalculate the
animated value.
If we try to query the animated transform value in between resetting it and the
next composite we will get back null. To avoid a race condition, in
ShadowLayersUpdated after potentially clearing the animated transform, we
synchronously update the async properties on the layer transform in order
to reinstate the animated transform (so it is there when we go to query it).
However we *only* do this when the mIsTesting flag is set which is true
whenever we have the refresh driver under test control. Furthermore, we only
do it when we already have a pending composite task to better match conditions
under regular operation.
In test_deferred_start.html, however, we specifically need to test without
putting the refresh driver under test control. As a result mIsTesting will be
false and we can encounter a race condition when querying the animated
transform.
To work around this, this patch makes us *also* update async properties
when fetching the animated transform value. The method for getting the
animated transform value is only used for testing so it should have no effect
on the regular compositing behavior.
It would seem that we could then remove the call from ShadowLayersUpdated but
doing this caused a small number of test cases to fail. In particular one test
for *opacity* in test_animations_omta.html was failing at the end of the
animation because we ended up with a stale opacity animation value on the
compositor which the synchronous update was previously removing. The test,
in this case, should be ignoring the value on the compositor but, unlike
transform, there is no flag for indicating whether or not the opacity on shadow
layers has been set by animations. As a result, this patch leaves the call that
triggers a synchronous update in test mode when updating shadow layers.
2015-03-17 12:38:12 +03:00
|
|
|
void
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::ApplyAsyncProperties(LayerTransactionParent* aLayerTree)
|
Bug 1113425 part 2 - Apply async properties when querying the animated transform; r=mattwoodrow
In order to test off-main thread animations, we have a method that will return
the animated transform value set on a shadow layer. This method will return null
if the transform was not set by animation.
However, in some situations we temporarily clear the animation transform. For
example, when we synchronize a composite layer with its content layer, we reset
the animation transform. Then, on the next composite, we will recalculate the
animated value.
If we try to query the animated transform value in between resetting it and the
next composite we will get back null. To avoid a race condition, in
ShadowLayersUpdated after potentially clearing the animated transform, we
synchronously update the async properties on the layer transform in order
to reinstate the animated transform (so it is there when we go to query it).
However we *only* do this when the mIsTesting flag is set which is true
whenever we have the refresh driver under test control. Furthermore, we only
do it when we already have a pending composite task to better match conditions
under regular operation.
In test_deferred_start.html, however, we specifically need to test without
putting the refresh driver under test control. As a result mIsTesting will be
false and we can encounter a race condition when querying the animated
transform.
To work around this, this patch makes us *also* update async properties
when fetching the animated transform value. The method for getting the
animated transform value is only used for testing so it should have no effect
on the regular compositing behavior.
It would seem that we could then remove the call from ShadowLayersUpdated but
doing this caused a small number of test cases to fail. In particular one test
for *opacity* in test_animations_omta.html was failing at the end of the
animation because we ended up with a stale opacity animation value on the
compositor which the synchronous update was previously removing. The test,
in this case, should be ignoring the value on the compositor but, unlike
transform, there is no flag for indicating whether or not the opacity on shadow
layers has been set by animations. As a result, this patch leaves the call that
triggers a synchronous update in test mode when updating shadow layers.
2015-03-17 12:38:12 +03:00
|
|
|
{
|
|
|
|
// NOTE: This should only be used for testing. For example, when mIsTesting is
|
|
|
|
// true or when called from test-only methods like
|
|
|
|
// LayerTransactionParent::RecvGetAnimationTransform.
|
|
|
|
|
2015-04-25 03:05:52 +03:00
|
|
|
// Synchronously update the layer tree
|
|
|
|
if (aLayerTree->GetRoot()) {
|
Bug 1113425 part 2 - Apply async properties when querying the animated transform; r=mattwoodrow
In order to test off-main thread animations, we have a method that will return
the animated transform value set on a shadow layer. This method will return null
if the transform was not set by animation.
However, in some situations we temporarily clear the animation transform. For
example, when we synchronize a composite layer with its content layer, we reset
the animation transform. Then, on the next composite, we will recalculate the
animated value.
If we try to query the animated transform value in between resetting it and the
next composite we will get back null. To avoid a race condition, in
ShadowLayersUpdated after potentially clearing the animated transform, we
synchronously update the async properties on the layer transform in order
to reinstate the animated transform (so it is there when we go to query it).
However we *only* do this when the mIsTesting flag is set which is true
whenever we have the refresh driver under test control. Furthermore, we only
do it when we already have a pending composite task to better match conditions
under regular operation.
In test_deferred_start.html, however, we specifically need to test without
putting the refresh driver under test control. As a result mIsTesting will be
false and we can encounter a race condition when querying the animated
transform.
To work around this, this patch makes us *also* update async properties
when fetching the animated transform value. The method for getting the
animated transform value is only used for testing so it should have no effect
on the regular compositing behavior.
It would seem that we could then remove the call from ShadowLayersUpdated but
doing this caused a small number of test cases to fail. In particular one test
for *opacity* in test_animations_omta.html was failing at the end of the
animation because we ended up with a stale opacity animation value on the
compositor which the synchronous update was previously removing. The test,
in this case, should be ignoring the value on the compositor but, unlike
transform, there is no flag for indicating whether or not the opacity on shadow
layers has been set by animations. As a result, this patch leaves the call that
triggers a synchronous update in test mode when updating shadow layers.
2015-03-17 12:38:12 +03:00
|
|
|
AutoResolveRefLayers resolve(mCompositionManager);
|
2015-04-25 03:05:52 +03:00
|
|
|
SetShadowProperties(mLayerManager->GetRoot());
|
|
|
|
|
2015-04-30 21:35:13 +03:00
|
|
|
TimeStamp time = mIsTesting ? mTestTime : mCompositorScheduler->GetLastComposeTime();
|
Bug 1113425 part 2 - Apply async properties when querying the animated transform; r=mattwoodrow
In order to test off-main thread animations, we have a method that will return
the animated transform value set on a shadow layer. This method will return null
if the transform was not set by animation.
However, in some situations we temporarily clear the animation transform. For
example, when we synchronize a composite layer with its content layer, we reset
the animation transform. Then, on the next composite, we will recalculate the
animated value.
If we try to query the animated transform value in between resetting it and the
next composite we will get back null. To avoid a race condition, in
ShadowLayersUpdated after potentially clearing the animated transform, we
synchronously update the async properties on the layer transform in order
to reinstate the animated transform (so it is there when we go to query it).
However we *only* do this when the mIsTesting flag is set which is true
whenever we have the refresh driver under test control. Furthermore, we only
do it when we already have a pending composite task to better match conditions
under regular operation.
In test_deferred_start.html, however, we specifically need to test without
putting the refresh driver under test control. As a result mIsTesting will be
false and we can encounter a race condition when querying the animated
transform.
To work around this, this patch makes us *also* update async properties
when fetching the animated transform value. The method for getting the
animated transform value is only used for testing so it should have no effect
on the regular compositing behavior.
It would seem that we could then remove the call from ShadowLayersUpdated but
doing this caused a small number of test cases to fail. In particular one test
for *opacity* in test_animations_omta.html was failing at the end of the
animation because we ended up with a stale opacity animation value on the
compositor which the synchronous update was previously removing. The test,
in this case, should be ignoring the value on the compositor but, unlike
transform, there is no flag for indicating whether or not the opacity on shadow
layers has been set by animations. As a result, this patch leaves the call that
triggers a synchronous update in test mode when updating shadow layers.
2015-03-17 12:38:12 +03:00
|
|
|
bool requestNextFrame =
|
2016-07-26 11:57:11 +03:00
|
|
|
mCompositionManager->TransformShadowTree(time, mVsyncRate,
|
2015-04-25 03:05:52 +03:00
|
|
|
AsyncCompositionManager::TransformsToSkip::APZ);
|
Bug 1113425 part 2 - Apply async properties when querying the animated transform; r=mattwoodrow
In order to test off-main thread animations, we have a method that will return
the animated transform value set on a shadow layer. This method will return null
if the transform was not set by animation.
However, in some situations we temporarily clear the animation transform. For
example, when we synchronize a composite layer with its content layer, we reset
the animation transform. Then, on the next composite, we will recalculate the
animated value.
If we try to query the animated transform value in between resetting it and the
next composite we will get back null. To avoid a race condition, in
ShadowLayersUpdated after potentially clearing the animated transform, we
synchronously update the async properties on the layer transform in order
to reinstate the animated transform (so it is there when we go to query it).
However we *only* do this when the mIsTesting flag is set which is true
whenever we have the refresh driver under test control. Furthermore, we only
do it when we already have a pending composite task to better match conditions
under regular operation.
In test_deferred_start.html, however, we specifically need to test without
putting the refresh driver under test control. As a result mIsTesting will be
false and we can encounter a race condition when querying the animated
transform.
To work around this, this patch makes us *also* update async properties
when fetching the animated transform value. The method for getting the
animated transform value is only used for testing so it should have no effect
on the regular compositing behavior.
It would seem that we could then remove the call from ShadowLayersUpdated but
doing this caused a small number of test cases to fail. In particular one test
for *opacity* in test_animations_omta.html was failing at the end of the
animation because we ended up with a stale opacity animation value on the
compositor which the synchronous update was previously removing. The test,
in this case, should be ignoring the value on the compositor but, unlike
transform, there is no flag for indicating whether or not the opacity on shadow
layers has been set by animations. As a result, this patch leaves the call that
triggers a synchronous update in test mode when updating shadow layers.
2015-03-17 12:38:12 +03:00
|
|
|
if (!requestNextFrame) {
|
|
|
|
CancelCurrentCompositeTask();
|
|
|
|
// Pretend we composited in case someone is waiting for this event.
|
2015-08-25 08:51:58 +03:00
|
|
|
TimeStamp now = TimeStamp::Now();
|
|
|
|
DidComposite(now, now);
|
Bug 1113425 part 2 - Apply async properties when querying the animated transform; r=mattwoodrow
In order to test off-main thread animations, we have a method that will return
the animated transform value set on a shadow layer. This method will return null
if the transform was not set by animation.
However, in some situations we temporarily clear the animation transform. For
example, when we synchronize a composite layer with its content layer, we reset
the animation transform. Then, on the next composite, we will recalculate the
animated value.
If we try to query the animated transform value in between resetting it and the
next composite we will get back null. To avoid a race condition, in
ShadowLayersUpdated after potentially clearing the animated transform, we
synchronously update the async properties on the layer transform in order
to reinstate the animated transform (so it is there when we go to query it).
However we *only* do this when the mIsTesting flag is set which is true
whenever we have the refresh driver under test control. Furthermore, we only
do it when we already have a pending composite task to better match conditions
under regular operation.
In test_deferred_start.html, however, we specifically need to test without
putting the refresh driver under test control. As a result mIsTesting will be
false and we can encounter a race condition when querying the animated
transform.
To work around this, this patch makes us *also* update async properties
when fetching the animated transform value. The method for getting the
animated transform value is only used for testing so it should have no effect
on the regular compositing behavior.
It would seem that we could then remove the call from ShadowLayersUpdated but
doing this caused a small number of test cases to fail. In particular one test
for *opacity* in test_animations_omta.html was failing at the end of the
animation because we ended up with a stale opacity animation value on the
compositor which the synchronous update was previously removing. The test,
in this case, should be ignoring the value on the compositor but, unlike
transform, there is no flag for indicating whether or not the opacity on shadow
layers has been set by animations. As a result, this patch leaves the call that
triggers a synchronous update in test mode when updating shadow layers.
2015-03-17 12:38:12 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-06-08 19:53:41 +03:00
|
|
|
bool
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::RecvGetFrameUniformity(FrameUniformityData* aOutData)
|
2015-06-08 19:53:41 +03:00
|
|
|
{
|
|
|
|
mCompositionManager->GetFrameUniformity(aOutData);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2014-05-08 19:32:00 +04:00
|
|
|
bool
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::RecvRequestOverfill()
|
2014-05-08 19:32:00 +04:00
|
|
|
{
|
|
|
|
uint32_t overfillRatio = mCompositor->GetFillRatio();
|
2015-11-02 08:53:26 +03:00
|
|
|
Unused << SendOverfill(overfillRatio);
|
2014-05-08 19:32:00 +04:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2015-06-19 15:25:41 +03:00
|
|
|
void
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::FlushApzRepaints(const LayerTransactionParent* aLayerTree)
|
2015-06-19 15:25:41 +03:00
|
|
|
{
|
|
|
|
MOZ_ASSERT(mApzcTreeManager);
|
|
|
|
uint64_t layersId = aLayerTree->GetId();
|
|
|
|
if (layersId == 0) {
|
|
|
|
// The request is coming from the parent-process layer tree, so we should
|
|
|
|
// use the compositor's root layer tree id.
|
|
|
|
layersId = mRootLayerTreeID;
|
|
|
|
}
|
|
|
|
mApzcTreeManager->FlushApzRepaints(layersId);
|
|
|
|
}
|
|
|
|
|
2014-05-08 03:56:48 +04:00
|
|
|
void
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::GetAPZTestData(const LayerTransactionParent* aLayerTree,
|
|
|
|
APZTestData* aOutData)
|
2014-05-08 03:56:48 +04:00
|
|
|
{
|
2015-01-13 21:26:26 +03:00
|
|
|
MonitorAutoLock lock(*sIndirectLayerTreesLock);
|
2014-05-08 03:56:48 +04:00
|
|
|
*aOutData = sIndirectLayerTrees[mRootLayerTreeID].mApzTestData;
|
|
|
|
}
|
|
|
|
|
2016-04-28 03:06:05 +03:00
|
|
|
class NotifyAPZConfirmedTargetTask : public Runnable
|
2015-04-14 19:24:32 +03:00
|
|
|
{
|
|
|
|
public:
|
2015-10-18 08:24:48 +03:00
|
|
|
explicit NotifyAPZConfirmedTargetTask(const RefPtr<APZCTreeManager>& aAPZCTM,
|
2015-04-14 19:24:32 +03:00
|
|
|
const uint64_t& aInputBlockId,
|
|
|
|
const nsTArray<ScrollableLayerGuid>& aTargets)
|
|
|
|
: mAPZCTM(aAPZCTM),
|
|
|
|
mInputBlockId(aInputBlockId),
|
|
|
|
mTargets(aTargets)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2016-04-28 03:06:05 +03:00
|
|
|
NS_IMETHOD Run() override {
|
2015-04-14 19:24:32 +03:00
|
|
|
mAPZCTM->SetTargetAPZC(mInputBlockId, mTargets);
|
2016-04-28 03:06:05 +03:00
|
|
|
return NS_OK;
|
2015-04-14 19:24:32 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<APZCTreeManager> mAPZCTM;
|
2015-04-14 19:24:32 +03:00
|
|
|
uint64_t mInputBlockId;
|
|
|
|
nsTArray<ScrollableLayerGuid> mTargets;
|
|
|
|
};
|
|
|
|
|
|
|
|
void
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::SetConfirmedTargetAPZC(const LayerTransactionParent* aLayerTree,
|
2015-04-14 19:24:32 +03:00
|
|
|
const uint64_t& aInputBlockId,
|
|
|
|
const nsTArray<ScrollableLayerGuid>& aTargets)
|
|
|
|
{
|
|
|
|
if (!mApzcTreeManager) {
|
|
|
|
return;
|
|
|
|
}
|
2016-04-28 03:06:05 +03:00
|
|
|
RefPtr<Runnable> task =
|
|
|
|
new NotifyAPZConfirmedTargetTask(mApzcTreeManager, aInputBlockId, aTargets);
|
|
|
|
APZThreadUtils::RunOnControllerThread(task.forget());
|
|
|
|
|
2015-04-14 19:24:32 +03:00
|
|
|
}
|
2014-05-08 03:56:48 +04:00
|
|
|
|
2013-08-18 10:46:16 +04:00
|
|
|
void
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::InitializeLayerManager(const nsTArray<LayersBackend>& aBackendHints)
|
2013-08-18 10:46:16 +04:00
|
|
|
{
|
|
|
|
NS_ASSERTION(!mLayerManager, "Already initialised mLayerManager");
|
2013-12-11 07:51:00 +04:00
|
|
|
NS_ASSERTION(!mCompositor, "Already initialised mCompositor");
|
2013-08-18 10:46:16 +04:00
|
|
|
|
2016-02-29 09:53:14 +03:00
|
|
|
mCompositor = NewCompositor(aBackendHints);
|
|
|
|
if (!mCompositor) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
mLayerManager = new LayerManagerComposite(mCompositor);
|
|
|
|
|
|
|
|
MonitorAutoLock lock(*sIndirectLayerTreesLock);
|
|
|
|
sIndirectLayerTrees[mRootLayerTreeID].mLayerManager = mLayerManager;
|
|
|
|
}
|
|
|
|
|
|
|
|
RefPtr<Compositor>
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::NewCompositor(const nsTArray<LayersBackend>& aBackendHints)
|
2016-02-29 09:53:14 +03:00
|
|
|
{
|
2013-08-18 10:46:16 +04:00
|
|
|
for (size_t i = 0; i < aBackendHints.Length(); ++i) {
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<Compositor> compositor;
|
2014-01-23 22:26:41 +04:00
|
|
|
if (aBackendHints[i] == LayersBackend::LAYERS_OPENGL) {
|
2016-03-25 11:38:55 +03:00
|
|
|
compositor = new CompositorOGL(this,
|
2016-07-01 11:15:16 +03:00
|
|
|
mWidget,
|
2013-12-09 05:40:58 +04:00
|
|
|
mEGLSurfaceSize.width,
|
|
|
|
mEGLSurfaceSize.height,
|
|
|
|
mUseExternalSurfaceSize);
|
2014-01-23 22:26:41 +04:00
|
|
|
} else if (aBackendHints[i] == LayersBackend::LAYERS_BASIC) {
|
2014-07-23 03:02:25 +04:00
|
|
|
#ifdef MOZ_WIDGET_GTK
|
2016-08-04 21:33:44 +03:00
|
|
|
if (gfxVars::UseXRender()) {
|
2016-07-01 11:15:16 +03:00
|
|
|
compositor = new X11BasicCompositor(this, mWidget);
|
2014-07-23 03:02:25 +04:00
|
|
|
} else
|
|
|
|
#endif
|
|
|
|
{
|
2016-07-01 11:15:16 +03:00
|
|
|
compositor = new BasicCompositor(this, mWidget);
|
2014-07-23 03:02:25 +04:00
|
|
|
}
|
2013-08-18 10:46:16 +04:00
|
|
|
#ifdef XP_WIN
|
2014-01-23 22:26:41 +04:00
|
|
|
} else if (aBackendHints[i] == LayersBackend::LAYERS_D3D11) {
|
2016-07-01 11:15:16 +03:00
|
|
|
compositor = new CompositorD3D11(this, mWidget);
|
2014-01-23 22:26:41 +04:00
|
|
|
} else if (aBackendHints[i] == LayersBackend::LAYERS_D3D9) {
|
2016-07-01 11:15:16 +03:00
|
|
|
compositor = new CompositorD3D9(this, mWidget);
|
2013-08-18 10:46:16 +04:00
|
|
|
#endif
|
|
|
|
}
|
2016-07-05 22:41:21 +03:00
|
|
|
nsCString failureReason;
|
|
|
|
if (compositor && compositor->Initialize(&failureReason)) {
|
|
|
|
if (failureReason.IsEmpty()){
|
|
|
|
failureReason = "SUCCESS";
|
|
|
|
}
|
2016-07-29 18:41:33 +03:00
|
|
|
|
|
|
|
// should only report success here
|
|
|
|
if (aBackendHints[i] == LayersBackend::LAYERS_OPENGL){
|
2016-07-05 22:41:21 +03:00
|
|
|
Telemetry::Accumulate(Telemetry::OPENGL_COMPOSITING_FAILURE_ID, failureReason);
|
|
|
|
}
|
|
|
|
#ifdef XP_WIN
|
2016-07-29 18:41:33 +03:00
|
|
|
else if (aBackendHints[i] == LayersBackend::LAYERS_D3D9){
|
2016-07-05 22:41:21 +03:00
|
|
|
Telemetry::Accumulate(Telemetry::D3D9_COMPOSITING_FAILURE_ID, failureReason);
|
|
|
|
}
|
2016-07-29 18:41:33 +03:00
|
|
|
else if (aBackendHints[i] == LayersBackend::LAYERS_D3D11){
|
2016-07-05 22:41:21 +03:00
|
|
|
Telemetry::Accumulate(Telemetry::D3D11_COMPOSITING_FAILURE_ID, failureReason);
|
|
|
|
}
|
|
|
|
#endif
|
2016-07-29 18:41:33 +03:00
|
|
|
|
2016-02-29 09:53:14 +03:00
|
|
|
compositor->SetCompositorID(mCompositorID);
|
|
|
|
return compositor;
|
2013-08-18 10:46:16 +04:00
|
|
|
}
|
2016-07-29 18:41:33 +03:00
|
|
|
|
|
|
|
// report any failure reasons here
|
|
|
|
if (aBackendHints[i] == LayersBackend::LAYERS_OPENGL){
|
|
|
|
Telemetry::Accumulate(Telemetry::OPENGL_COMPOSITING_FAILURE_ID, failureReason);
|
|
|
|
}
|
|
|
|
#ifdef XP_WIN
|
|
|
|
else if (aBackendHints[i] == LayersBackend::LAYERS_D3D9){
|
|
|
|
Telemetry::Accumulate(Telemetry::D3D9_COMPOSITING_FAILURE_ID, failureReason);
|
|
|
|
}
|
|
|
|
else if (aBackendHints[i] == LayersBackend::LAYERS_D3D11){
|
|
|
|
Telemetry::Accumulate(Telemetry::D3D11_COMPOSITING_FAILURE_ID, failureReason);
|
|
|
|
}
|
|
|
|
#endif
|
2013-08-18 10:46:16 +04:00
|
|
|
}
|
2016-02-29 09:53:14 +03:00
|
|
|
|
|
|
|
return nullptr;
|
2013-08-18 10:46:16 +04:00
|
|
|
}
|
|
|
|
|
2013-04-24 22:42:40 +04:00
|
|
|
PLayerTransactionParent*
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::AllocPLayerTransactionParent(const nsTArray<LayersBackend>& aBackendHints,
|
|
|
|
const uint64_t& aId,
|
|
|
|
TextureFactoryIdentifier* aTextureFactoryIdentifier,
|
2013-08-04 11:46:17 +04:00
|
|
|
bool *aSuccess)
|
2012-01-07 02:52:32 +04:00
|
|
|
{
|
2012-07-18 03:59:45 +04:00
|
|
|
MOZ_ASSERT(aId == 0);
|
|
|
|
|
2013-08-18 10:46:16 +04:00
|
|
|
InitializeLayerManager(aBackendHints);
|
2013-05-01 04:42:05 +04:00
|
|
|
|
2013-08-18 10:46:16 +04:00
|
|
|
if (!mLayerManager) {
|
|
|
|
NS_WARNING("Failed to initialise Compositor");
|
2013-08-04 11:46:17 +04:00
|
|
|
*aSuccess = false;
|
2015-04-01 11:40:35 +03:00
|
|
|
LayerTransactionParent* p = new LayerTransactionParent(nullptr, this, 0);
|
2013-11-27 19:18:38 +04:00
|
|
|
p->AddIPDLReference();
|
|
|
|
return p;
|
2013-05-01 04:42:05 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
mCompositionManager = new AsyncCompositionManager(mLayerManager);
|
2013-11-27 19:18:38 +04:00
|
|
|
*aSuccess = true;
|
2013-05-01 04:42:05 +04:00
|
|
|
|
2013-12-09 05:40:59 +04:00
|
|
|
*aTextureFactoryIdentifier = mCompositor->GetTextureFactoryIdentifier();
|
2015-04-01 11:40:35 +03:00
|
|
|
LayerTransactionParent* p = new LayerTransactionParent(mLayerManager, this, 0);
|
2013-11-27 19:18:38 +04:00
|
|
|
p->AddIPDLReference();
|
|
|
|
return p;
|
2011-12-16 00:07:19 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::DeallocPLayerTransactionParent(PLayerTransactionParent* actor)
|
2011-12-16 00:07:19 +04:00
|
|
|
{
|
2013-11-27 19:18:38 +04:00
|
|
|
static_cast<LayerTransactionParent*>(actor)->ReleaseIPDLReference();
|
2011-12-16 00:07:19 +04:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-06-22 03:58:55 +03:00
|
|
|
CompositorBridgeParent* CompositorBridgeParent::GetCompositorBridgeParent(uint64_t id)
|
2012-07-13 23:38:09 +04:00
|
|
|
{
|
|
|
|
CompositorMap::iterator it = sCompositorMap->find(id);
|
2012-07-30 18:20:58 +04:00
|
|
|
return it != sCompositorMap->end() ? it->second : nullptr;
|
2012-07-13 23:38:09 +04:00
|
|
|
}
|
|
|
|
|
2016-03-22 21:08:38 +03:00
|
|
|
void CompositorBridgeParent::AddCompositor(CompositorBridgeParent* compositor, uint64_t* outID)
|
2012-07-13 23:38:09 +04:00
|
|
|
{
|
2012-08-22 19:56:38 +04:00
|
|
|
static uint64_t sNextID = 1;
|
Bug 825928: Land layers refactoring. r=jrmuizel,bas,nical,mattwoodrow,roc,nrc,benwa,bjacob,jgilbert,kchen CLOSED TREE
Please contact Bas Schouten <bschouten@mozilla.com>, Nicolas Silva <nsilva@mozilla.com> or Nicholas Cameron <ncameron@mozilla.com> with general questions. Below is a rough list of authors to contact with specific questions.
Authors:
gfx/layers/Compositor.* gfx/layers/Effects.h - Compositor Interface - bas,nrc,nical
gfx/layers/d3d* - D3D9/D3D10 - bas
gfx/layers/ThebesLayer* - ThebesLayers - nrc,bas
gfx/layers/composite/* - CompositeLayers - nrc,nical
gfx/layers/client/* - Client - nrc,nical,bas
gfx/layers/*Image* - nical
gfx/layers/ipc ipc - IPC - nical
gfx/layers/opengl - CompositorOGL - nrc,nical
gfx/2d - bas,nrc
gfx/gl - GLContext - bjacob
dom/* layout/* - DOM - mattwoodrow
2013-04-10 13:20:52 +04:00
|
|
|
|
2012-07-13 23:38:09 +04:00
|
|
|
++sNextID;
|
|
|
|
(*sCompositorMap)[sNextID] = compositor;
|
|
|
|
*outID = sNextID;
|
|
|
|
}
|
|
|
|
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent* CompositorBridgeParent::RemoveCompositor(uint64_t id)
|
2012-07-13 23:38:09 +04:00
|
|
|
{
|
|
|
|
CompositorMap::iterator it = sCompositorMap->find(id);
|
|
|
|
if (it == sCompositorMap->end()) {
|
2012-07-30 18:20:58 +04:00
|
|
|
return nullptr;
|
2012-07-13 23:38:09 +04:00
|
|
|
}
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent *retval = it->second;
|
2012-07-13 23:38:09 +04:00
|
|
|
sCompositorMap->erase(it);
|
Bug 825928: Land layers refactoring. r=jrmuizel,bas,nical,mattwoodrow,roc,nrc,benwa,bjacob,jgilbert,kchen CLOSED TREE
Please contact Bas Schouten <bschouten@mozilla.com>, Nicolas Silva <nsilva@mozilla.com> or Nicholas Cameron <ncameron@mozilla.com> with general questions. Below is a rough list of authors to contact with specific questions.
Authors:
gfx/layers/Compositor.* gfx/layers/Effects.h - Compositor Interface - bas,nrc,nical
gfx/layers/d3d* - D3D9/D3D10 - bas
gfx/layers/ThebesLayer* - ThebesLayers - nrc,bas
gfx/layers/composite/* - CompositeLayers - nrc,nical
gfx/layers/client/* - Client - nrc,nical,bas
gfx/layers/*Image* - nical
gfx/layers/ipc ipc - IPC - nical
gfx/layers/opengl - CompositorOGL - nrc,nical
gfx/2d - bas,nrc
gfx/gl - GLContext - bjacob
dom/* layout/* - DOM - mattwoodrow
2013-04-10 13:20:52 +04:00
|
|
|
return retval;
|
2012-07-13 23:38:09 +04:00
|
|
|
}
|
|
|
|
|
2016-07-19 21:56:07 +03:00
|
|
|
void
|
|
|
|
CompositorBridgeParent::NotifyVsync(const TimeStamp& aTimeStamp, const uint64_t& aLayersId)
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_GPU);
|
|
|
|
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
|
|
|
|
|
|
|
MonitorAutoLock lock(*sIndirectLayerTreesLock);
|
|
|
|
auto it = sIndirectLayerTrees.find(aLayersId);
|
|
|
|
if (it == sIndirectLayerTrees.end())
|
|
|
|
return;
|
|
|
|
|
|
|
|
CompositorBridgeParent* cbp = it->second.mParent;
|
|
|
|
if (!cbp || !cbp->mWidget)
|
|
|
|
return;
|
|
|
|
|
|
|
|
RefPtr<VsyncObserver> obs = cbp->mWidget->GetVsyncObserver();
|
|
|
|
if (!obs)
|
|
|
|
return;
|
|
|
|
|
|
|
|
obs->NotifyVsync(aTimeStamp);
|
|
|
|
}
|
|
|
|
|
2013-07-12 06:32:09 +04:00
|
|
|
bool
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::RecvNotifyChildCreated(const uint64_t& child)
|
2013-07-12 06:32:09 +04:00
|
|
|
{
|
2015-01-17 18:25:57 +03:00
|
|
|
MonitorAutoLock lock(*sIndirectLayerTreesLock);
|
2013-07-12 06:32:09 +04:00
|
|
|
NotifyChildCreated(child);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::NotifyChildCreated(uint64_t aChild)
|
2013-07-12 06:32:09 +04:00
|
|
|
{
|
2015-01-17 18:25:57 +03:00
|
|
|
sIndirectLayerTreesLock->AssertCurrentThreadOwns();
|
2013-07-12 06:32:09 +04:00
|
|
|
sIndirectLayerTrees[aChild].mParent = this;
|
2013-12-09 05:40:58 +04:00
|
|
|
sIndirectLayerTrees[aChild].mLayerManager = mLayerManager;
|
2013-07-12 06:32:09 +04:00
|
|
|
}
|
|
|
|
|
2016-01-08 22:17:39 +03:00
|
|
|
/* static */ bool
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::UpdateRemoteContentController(uint64_t aLayersId,
|
|
|
|
dom::ContentParent* aContent,
|
|
|
|
const dom::TabId& aTabId,
|
|
|
|
dom::TabParent* aTopLevel)
|
2016-01-08 22:17:39 +03:00
|
|
|
{
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
|
|
|
|
MonitorAutoLock lock(*sIndirectLayerTreesLock);
|
|
|
|
LayerTreeState& state = sIndirectLayerTrees[aLayersId];
|
|
|
|
// RemoteContentController needs to know the layers id and the top level
|
|
|
|
// TabParent, so we pass that to its constructor here and then set up the
|
|
|
|
// PAPZ protocol by calling SendPAPZConstructor (and pass in the tab id for
|
|
|
|
// the PBrowser that it corresponds to).
|
|
|
|
RefPtr<RemoteContentController> controller =
|
|
|
|
new RemoteContentController(aLayersId, aTopLevel);
|
|
|
|
if (!aContent->SendPAPZConstructor(controller, aTabId)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
state.mController = controller;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2014-10-15 02:11:38 +04:00
|
|
|
bool
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::RecvAdoptChild(const uint64_t& child)
|
2014-10-15 02:11:38 +04:00
|
|
|
{
|
2016-01-08 22:17:39 +03:00
|
|
|
RefPtr<GeckoContentController> controller;
|
|
|
|
{
|
|
|
|
MonitorAutoLock lock(*sIndirectLayerTreesLock);
|
|
|
|
NotifyChildCreated(child);
|
|
|
|
if (sIndirectLayerTrees[child].mLayerTree) {
|
|
|
|
sIndirectLayerTrees[child].mLayerTree->mLayerManager = mLayerManager;
|
|
|
|
}
|
|
|
|
if (sIndirectLayerTrees[child].mRoot) {
|
|
|
|
sIndirectLayerTrees[child].mRoot->AsLayerComposite()->SetLayerManager(mLayerManager);
|
|
|
|
}
|
|
|
|
controller = sIndirectLayerTrees[child].mController;
|
2014-10-15 02:11:38 +04:00
|
|
|
}
|
2016-01-08 22:17:39 +03:00
|
|
|
|
|
|
|
// Calling ChildAdopted on controller will acquire a lock, to avoid a
|
|
|
|
// potential deadlock between that lock and sIndirectLayerTreesLock we
|
|
|
|
// release sIndirectLayerTreesLock first before calling ChildAdopted.
|
|
|
|
if (mApzcTreeManager && controller) {
|
|
|
|
controller->ChildAdopted();
|
2014-10-15 02:11:38 +04:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2012-07-20 10:48:27 +04:00
|
|
|
static void
|
2014-04-24 12:40:35 +04:00
|
|
|
EraseLayerState(uint64_t aId)
|
2012-07-20 10:48:27 +04:00
|
|
|
{
|
2015-01-13 21:26:26 +03:00
|
|
|
MonitorAutoLock lock(*sIndirectLayerTreesLock);
|
2016-03-19 04:38:57 +03:00
|
|
|
|
|
|
|
auto iter = sIndirectLayerTrees.find(aId);
|
|
|
|
if (iter != sIndirectLayerTrees.end()) {
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent* parent = iter->second.mParent;
|
2016-03-19 04:38:57 +03:00
|
|
|
if (parent) {
|
2016-04-21 11:22:10 +03:00
|
|
|
parent->ClearVisibleRegions(aId, Nothing());
|
2016-03-19 04:38:57 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
sIndirectLayerTrees.erase(iter);
|
|
|
|
}
|
2012-07-20 10:48:27 +04:00
|
|
|
}
|
|
|
|
|
2014-04-24 12:40:35 +04:00
|
|
|
/*static*/ void
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::DeallocateLayerTreeId(uint64_t aId)
|
2014-04-24 12:40:35 +04:00
|
|
|
{
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
2014-05-12 01:03:00 +04:00
|
|
|
// Here main thread notifies compositor to remove an element from
|
|
|
|
// sIndirectLayerTrees. This removed element might be queried soon.
|
|
|
|
// Checking the elements of sIndirectLayerTrees exist or not before using.
|
2015-06-17 17:33:00 +03:00
|
|
|
if (!CompositorLoop()) {
|
|
|
|
gfxCriticalError() << "Attempting to post to a invalid Compositor Loop";
|
|
|
|
return;
|
|
|
|
}
|
2016-04-28 03:06:05 +03:00
|
|
|
CompositorLoop()->PostTask(NewRunnableFunction(&EraseLayerState, aId));
|
2014-04-24 12:40:35 +04:00
|
|
|
}
|
|
|
|
|
2012-07-20 10:48:27 +04:00
|
|
|
static void
|
|
|
|
UpdateControllerForLayersId(uint64_t aLayersId,
|
2013-07-30 22:03:40 +04:00
|
|
|
GeckoContentController* aController)
|
2012-07-20 10:48:27 +04:00
|
|
|
{
|
2013-07-30 22:03:40 +04:00
|
|
|
// Adopt ref given to us by SetControllerForLayerTree()
|
2015-01-13 21:26:26 +03:00
|
|
|
MonitorAutoLock lock(*sIndirectLayerTreesLock);
|
2012-07-20 10:48:27 +04:00
|
|
|
sIndirectLayerTrees[aLayersId].mController =
|
2013-07-30 22:03:40 +04:00
|
|
|
already_AddRefed<GeckoContentController>(aController);
|
2012-07-20 10:48:27 +04:00
|
|
|
}
|
|
|
|
|
2015-09-25 20:54:11 +03:00
|
|
|
ScopedLayerTreeRegistration::ScopedLayerTreeRegistration(APZCTreeManager* aApzctm,
|
|
|
|
uint64_t aLayersId,
|
2013-07-30 22:03:41 +04:00
|
|
|
Layer* aRoot,
|
|
|
|
GeckoContentController* aController)
|
|
|
|
: mLayersId(aLayersId)
|
|
|
|
{
|
2015-01-13 21:26:26 +03:00
|
|
|
EnsureLayerTreeMapReady();
|
|
|
|
MonitorAutoLock lock(*sIndirectLayerTreesLock);
|
2013-07-30 22:03:41 +04:00
|
|
|
sIndirectLayerTrees[aLayersId].mRoot = aRoot;
|
|
|
|
sIndirectLayerTrees[aLayersId].mController = aController;
|
|
|
|
}
|
|
|
|
|
|
|
|
ScopedLayerTreeRegistration::~ScopedLayerTreeRegistration()
|
|
|
|
{
|
2015-01-13 21:26:26 +03:00
|
|
|
MonitorAutoLock lock(*sIndirectLayerTreesLock);
|
2013-07-30 22:03:41 +04:00
|
|
|
sIndirectLayerTrees.erase(mLayersId);
|
2012-07-20 10:48:27 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/*static*/ void
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::SetControllerForLayerTree(uint64_t aLayersId,
|
|
|
|
GeckoContentController* aController)
|
2012-07-20 10:48:27 +04:00
|
|
|
{
|
|
|
|
// This ref is adopted by UpdateControllerForLayersId().
|
|
|
|
aController->AddRef();
|
2016-04-28 03:06:05 +03:00
|
|
|
CompositorLoop()->PostTask(NewRunnableFunction(&UpdateControllerForLayersId,
|
2012-07-20 10:48:27 +04:00
|
|
|
aLayersId,
|
|
|
|
aController));
|
|
|
|
}
|
|
|
|
|
2016-05-23 10:27:51 +03:00
|
|
|
/*static*/ already_AddRefed<APZCTreeManager>
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::GetAPZCTreeManager(uint64_t aLayersId)
|
2013-07-30 22:03:40 +04:00
|
|
|
{
|
2015-11-03 19:12:46 +03:00
|
|
|
EnsureLayerTreeMapReady();
|
2015-11-27 03:20:04 +03:00
|
|
|
MonitorAutoLock lock(*sIndirectLayerTreesLock);
|
|
|
|
LayerTreeMap::iterator cit = sIndirectLayerTrees.find(aLayersId);
|
|
|
|
if (sIndirectLayerTrees.end() == cit) {
|
|
|
|
return nullptr;
|
2013-07-30 22:03:40 +04:00
|
|
|
}
|
2015-11-27 03:20:04 +03:00
|
|
|
LayerTreeState* lts = &cit->second;
|
2016-05-23 10:27:51 +03:00
|
|
|
|
|
|
|
RefPtr<APZCTreeManager> apzctm = lts->mParent
|
|
|
|
? lts->mParent->mApzcTreeManager.get()
|
|
|
|
: nullptr;
|
|
|
|
return apzctm.forget();
|
2013-07-30 22:03:40 +04:00
|
|
|
}
|
|
|
|
|
2014-10-02 00:01:59 +04:00
|
|
|
static void
|
|
|
|
InsertVsyncProfilerMarker(TimeStamp aVsyncTimestamp)
|
|
|
|
{
|
|
|
|
#ifdef MOZ_ENABLE_PROFILER_SPS
|
2016-05-16 09:40:13 +03:00
|
|
|
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
2014-10-02 00:01:59 +04:00
|
|
|
VsyncPayload* payload = new VsyncPayload(aVsyncTimestamp);
|
|
|
|
PROFILER_MARKER_PAYLOAD("VsyncTimestamp", payload);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
/*static */ void
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::PostInsertVsyncProfilerMarker(TimeStamp aVsyncTimestamp)
|
2014-10-02 00:01:59 +04:00
|
|
|
{
|
2015-03-14 04:14:11 +03:00
|
|
|
// Called in the vsync thread
|
2016-05-16 09:38:34 +03:00
|
|
|
if (profiler_is_active() && CompositorThreadHolder::IsActive()) {
|
2016-04-28 03:06:05 +03:00
|
|
|
CompositorLoop()->PostTask(
|
2014-10-02 00:01:59 +04:00
|
|
|
NewRunnableFunction(InsertVsyncProfilerMarker, aVsyncTimestamp));
|
|
|
|
}
|
|
|
|
}
|
2013-12-09 05:40:59 +04:00
|
|
|
|
2016-07-01 11:15:16 +03:00
|
|
|
widget::PCompositorWidgetParent*
|
|
|
|
CompositorBridgeParent::AllocPCompositorWidgetParent(const CompositorWidgetInitData& aInitData)
|
|
|
|
{
|
|
|
|
#if defined(MOZ_WIDGET_SUPPORTS_OOP_COMPOSITING)
|
|
|
|
if (mWidget) {
|
|
|
|
// Should not create two widgets on the same compositor.
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
widget::CompositorWidgetParent* widget =
|
|
|
|
new widget::CompositorWidgetParent(aInitData);
|
|
|
|
widget->AddRef();
|
|
|
|
|
|
|
|
// Sending the constructor acts as initialization as well.
|
|
|
|
mWidget = widget;
|
|
|
|
return widget;
|
|
|
|
#else
|
|
|
|
return nullptr;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
CompositorBridgeParent::DeallocPCompositorWidgetParent(PCompositorWidgetParent* aActor)
|
|
|
|
{
|
|
|
|
#if defined(MOZ_WIDGET_SUPPORTS_OOP_COMPOSITING)
|
|
|
|
static_cast<widget::CompositorWidgetParent*>(aActor)->Release();
|
|
|
|
return true;
|
|
|
|
#else
|
|
|
|
return false;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2012-07-18 03:59:45 +04:00
|
|
|
/**
|
2016-03-22 21:07:08 +03:00
|
|
|
* This class handles layer updates pushed directly from child processes to
|
2016-03-22 21:08:38 +03:00
|
|
|
* the compositor thread. It's associated with a CompositorBridgeParent on the
|
2016-03-22 21:07:08 +03:00
|
|
|
* compositor thread. While it uses the PCompositorBridge protocol to manage
|
|
|
|
* these updates, it doesn't actually drive compositing itself. For that it
|
2016-03-22 21:08:38 +03:00
|
|
|
* hands off work to the CompositorBridgeParent it's associated with.
|
2012-07-18 03:59:45 +04:00
|
|
|
*/
|
2016-03-22 21:08:38 +03:00
|
|
|
class CrossProcessCompositorBridgeParent final : public PCompositorBridgeParent,
|
2016-04-13 00:04:50 +03:00
|
|
|
public ShadowLayersManager,
|
2016-06-15 14:28:10 +03:00
|
|
|
public CompositorBridgeParentIPCAllocator,
|
2016-04-13 00:04:50 +03:00
|
|
|
public ShmemAllocator
|
2012-07-18 03:59:45 +04:00
|
|
|
{
|
2016-03-22 21:08:38 +03:00
|
|
|
friend class CompositorBridgeParent;
|
2012-07-18 03:59:45 +04:00
|
|
|
|
|
|
|
public:
|
2016-07-07 04:51:20 +03:00
|
|
|
explicit CrossProcessCompositorBridgeParent()
|
2016-07-20 02:59:30 +03:00
|
|
|
: mNotifyAfterRemotePaint(false)
|
2015-11-24 04:50:51 +03:00
|
|
|
, mDestroyCalled(false)
|
2014-07-04 22:04:11 +04:00
|
|
|
{
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
}
|
2012-07-18 03:59:45 +04:00
|
|
|
|
2016-07-18 07:24:28 +03:00
|
|
|
void Bind(Endpoint<PCompositorBridgeParent>&& aEndpoint) {
|
|
|
|
if (!aEndpoint.Bind(this, nullptr)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
mSelfRef = this;
|
|
|
|
}
|
|
|
|
|
2013-06-03 14:14:37 +04:00
|
|
|
// IToplevelProtocol::CloneToplevel()
|
|
|
|
virtual IToplevelProtocol*
|
|
|
|
CloneToplevel(const InfallibleTArray<mozilla::ipc::ProtocolFdMapping>& aFds,
|
|
|
|
base::ProcessHandle aPeerProcess,
|
2015-03-21 19:28:04 +03:00
|
|
|
mozilla::ipc::ProtocolCloneContext* aCtx) override;
|
2013-06-03 14:14:37 +04:00
|
|
|
|
2015-03-21 19:28:04 +03:00
|
|
|
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
|
2012-07-18 03:59:45 +04:00
|
|
|
|
|
|
|
// FIXME/bug 774388: work out what shutdown protocol we need.
|
2016-07-18 07:24:28 +03:00
|
|
|
virtual bool RecvInitialize(const uint64_t& aRootLayerTreeId) override { return false; }
|
2015-03-21 19:28:04 +03:00
|
|
|
virtual bool RecvRequestOverfill() override { return true; }
|
2015-11-24 04:50:51 +03:00
|
|
|
virtual bool RecvWillClose() override { return true; }
|
2015-03-21 19:28:04 +03:00
|
|
|
virtual bool RecvPause() override { return true; }
|
|
|
|
virtual bool RecvResume() override { return true; }
|
|
|
|
virtual bool RecvNotifyChildCreated(const uint64_t& child) override;
|
|
|
|
virtual bool RecvAdoptChild(const uint64_t& child) override { return false; }
|
2012-10-04 11:05:24 +04:00
|
|
|
virtual bool RecvMakeSnapshot(const SurfaceDescriptor& aInSnapshot,
|
2015-04-21 18:04:57 +03:00
|
|
|
const gfx::IntRect& aRect) override
|
2012-10-04 11:05:24 +04:00
|
|
|
{ return true; }
|
2015-03-21 19:28:04 +03:00
|
|
|
virtual bool RecvFlushRendering() override { return true; }
|
2016-02-24 06:50:09 +03:00
|
|
|
virtual bool RecvForcePresent() override { return true; }
|
2015-03-21 19:28:04 +03:00
|
|
|
virtual bool RecvNotifyRegionInvalidated(const nsIntRegion& aRegion) override { return true; }
|
|
|
|
virtual bool RecvStartFrameTimeRecording(const int32_t& aBufferSize, uint32_t* aOutStartIndex) override { return true; }
|
|
|
|
virtual bool RecvStopFrameTimeRecording(const uint32_t& aStartIndex, InfallibleTArray<float>* intervals) override { return true; }
|
2016-03-19 04:38:57 +03:00
|
|
|
|
2016-04-21 11:22:10 +03:00
|
|
|
virtual bool RecvClearVisibleRegions(const uint64_t& aLayersId,
|
|
|
|
const uint32_t& aPresShellId) override
|
2016-03-19 04:38:57 +03:00
|
|
|
{
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent* parent;
|
2016-03-19 04:38:57 +03:00
|
|
|
{ // scope lock
|
|
|
|
MonitorAutoLock lock(*sIndirectLayerTreesLock);
|
|
|
|
parent = sIndirectLayerTrees[aLayersId].mParent;
|
|
|
|
}
|
2016-04-21 11:22:10 +03:00
|
|
|
|
|
|
|
if (!parent) {
|
|
|
|
return false;
|
2016-03-19 04:38:57 +03:00
|
|
|
}
|
2016-04-21 11:22:10 +03:00
|
|
|
|
|
|
|
parent->ClearVisibleRegions(aLayersId, Some(aPresShellId));
|
2016-03-19 04:38:57 +03:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-04-21 11:22:10 +03:00
|
|
|
virtual bool RecvUpdateVisibleRegion(const VisibilityCounter& aCounter,
|
|
|
|
const ScrollableLayerGuid& aGuid,
|
|
|
|
const CSSIntRegion& aRegion) override
|
2016-03-19 04:38:57 +03:00
|
|
|
{
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent* parent;
|
2016-03-19 04:38:57 +03:00
|
|
|
{ // scope lock
|
|
|
|
MonitorAutoLock lock(*sIndirectLayerTreesLock);
|
|
|
|
parent = sIndirectLayerTrees[aGuid.mLayersId].mParent;
|
|
|
|
}
|
2016-04-21 11:22:10 +03:00
|
|
|
|
|
|
|
if (!parent) {
|
|
|
|
return false;
|
2016-03-19 04:38:57 +03:00
|
|
|
}
|
2016-04-21 11:22:10 +03:00
|
|
|
|
|
|
|
parent->UpdateVisibleRegion(aCounter, aGuid, aRegion);
|
2016-03-19 04:38:57 +03:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-07-18 11:54:02 +03:00
|
|
|
virtual bool RecvAllPluginsCaptured() override { return true; }
|
|
|
|
|
2015-06-08 19:53:41 +03:00
|
|
|
virtual bool RecvGetFrameUniformity(FrameUniformityData* aOutData) override
|
|
|
|
{
|
|
|
|
// Don't support calculating frame uniformity on the child process and
|
|
|
|
// this is just a stub for now.
|
|
|
|
MOZ_ASSERT(false);
|
|
|
|
return true;
|
|
|
|
}
|
2012-07-18 03:59:45 +04:00
|
|
|
|
2014-05-23 22:19:00 +04:00
|
|
|
/**
|
2016-03-22 21:08:38 +03:00
|
|
|
* Tells this CompositorBridgeParent to send a message when the compositor has received the transaction.
|
2014-05-23 22:19:00 +04:00
|
|
|
*/
|
2015-03-21 19:28:04 +03:00
|
|
|
virtual bool RecvRequestNotifyAfterRemotePaint() override;
|
2014-05-23 22:19:00 +04:00
|
|
|
|
2013-04-24 22:42:40 +04:00
|
|
|
virtual PLayerTransactionParent*
|
2013-08-18 10:46:16 +04:00
|
|
|
AllocPLayerTransactionParent(const nsTArray<LayersBackend>& aBackendHints,
|
2013-07-08 19:48:39 +04:00
|
|
|
const uint64_t& aId,
|
2013-08-04 11:46:17 +04:00
|
|
|
TextureFactoryIdentifier* aTextureFactoryIdentifier,
|
2015-03-21 19:28:04 +03:00
|
|
|
bool *aSuccess) override;
|
2012-07-18 03:59:45 +04:00
|
|
|
|
2015-03-21 19:28:04 +03:00
|
|
|
virtual bool DeallocPLayerTransactionParent(PLayerTransactionParent* aLayers) override;
|
2013-04-24 22:42:40 +04:00
|
|
|
|
|
|
|
virtual void ShadowLayersUpdated(LayerTransactionParent* aLayerTree,
|
2014-05-29 01:42:14 +04:00
|
|
|
const uint64_t& aTransactionId,
|
2012-07-24 23:01:09 +04:00
|
|
|
const TargetConfig& aTargetConfig,
|
2015-01-29 22:41:55 +03:00
|
|
|
const InfallibleTArray<PluginWindowData>& aPlugins,
|
2013-12-16 09:38:42 +04:00
|
|
|
bool aIsFirstPaint,
|
2014-05-07 01:26:13 +04:00
|
|
|
bool aScheduleComposite,
|
2014-05-31 02:52:43 +04:00
|
|
|
uint32_t aPaintSequenceNumber,
|
2015-08-18 21:27:20 +03:00
|
|
|
bool aIsRepeatTransaction,
|
2016-05-16 21:53:44 +03:00
|
|
|
int32_t /*aPaintSyncId: unused*/,
|
|
|
|
bool aHitTestUpdate) override;
|
2015-03-21 19:28:04 +03:00
|
|
|
virtual void ForceComposite(LayerTransactionParent* aLayerTree) override;
|
|
|
|
virtual void NotifyClearCachedResources(LayerTransactionParent* aLayerTree) override;
|
2014-03-22 01:59:57 +04:00
|
|
|
virtual bool SetTestSampleTime(LayerTransactionParent* aLayerTree,
|
2015-03-21 19:28:04 +03:00
|
|
|
const TimeStamp& aTime) override;
|
|
|
|
virtual void LeaveTestMode(LayerTransactionParent* aLayerTree) override;
|
2015-04-21 06:00:33 +03:00
|
|
|
virtual void ApplyAsyncProperties(LayerTransactionParent* aLayerTree)
|
|
|
|
override;
|
2015-06-19 15:25:41 +03:00
|
|
|
virtual void FlushApzRepaints(const LayerTransactionParent* aLayerTree) override;
|
2014-05-08 03:56:48 +04:00
|
|
|
virtual void GetAPZTestData(const LayerTransactionParent* aLayerTree,
|
2015-03-21 19:28:04 +03:00
|
|
|
APZTestData* aOutData) override;
|
2015-04-14 19:24:32 +03:00
|
|
|
virtual void SetConfirmedTargetAPZC(const LayerTransactionParent* aLayerTree,
|
|
|
|
const uint64_t& aInputBlockId,
|
|
|
|
const nsTArray<ScrollableLayerGuid>& aTargets) override;
|
2012-07-18 03:59:45 +04:00
|
|
|
|
2015-03-21 19:28:04 +03:00
|
|
|
virtual AsyncCompositionManager* GetCompositionManager(LayerTransactionParent* aParent) override;
|
2015-10-06 22:23:24 +03:00
|
|
|
virtual bool RecvRemotePluginsReady() override { return false; }
|
2016-03-25 11:35:07 +03:00
|
|
|
virtual bool RecvAcknowledgeCompositorUpdate(const uint64_t& aLayersId) override;
|
2014-02-25 02:45:40 +04:00
|
|
|
|
2015-09-09 02:14:51 +03:00
|
|
|
void DidComposite(uint64_t aId,
|
|
|
|
TimeStamp& aCompositeStart,
|
|
|
|
TimeStamp& aCompositeEnd);
|
2014-06-19 06:28:59 +04:00
|
|
|
|
2016-04-13 00:04:50 +03:00
|
|
|
virtual PTextureParent* AllocPTextureParent(const SurfaceDescriptor& aSharedData,
|
|
|
|
const LayersBackend& aLayersBackend,
|
|
|
|
const TextureFlags& aFlags,
|
2016-06-15 14:28:10 +03:00
|
|
|
const uint64_t& aId,
|
|
|
|
const uint64_t& aSerial) override;
|
2016-04-13 00:04:50 +03:00
|
|
|
|
|
|
|
virtual bool DeallocPTextureParent(PTextureParent* actor) override;
|
|
|
|
|
|
|
|
virtual bool IsSameProcess() const override;
|
|
|
|
|
|
|
|
virtual ShmemAllocator* AsShmemAllocator() override { return this; }
|
|
|
|
|
|
|
|
virtual bool AllocShmem(size_t aSize,
|
|
|
|
mozilla::ipc::SharedMemory::SharedMemoryType aType,
|
|
|
|
mozilla::ipc::Shmem* aShmem) override;
|
|
|
|
|
|
|
|
virtual bool AllocUnsafeShmem(size_t aSize,
|
|
|
|
mozilla::ipc::SharedMemory::SharedMemoryType aType,
|
|
|
|
mozilla::ipc::Shmem* aShmem) override;
|
|
|
|
|
|
|
|
virtual void DeallocShmem(mozilla::ipc::Shmem& aShmem) override;
|
|
|
|
|
2016-05-19 16:04:14 +03:00
|
|
|
virtual base::ProcessId GetChildProcessId() override
|
|
|
|
{
|
|
|
|
return OtherPid();
|
|
|
|
}
|
|
|
|
|
2016-06-15 14:28:10 +03:00
|
|
|
virtual void SendAsyncMessage(const InfallibleTArray<AsyncParentMessageData>& aMessage) override
|
|
|
|
{
|
|
|
|
Unused << SendParentAsyncMessages(aMessage);
|
|
|
|
}
|
|
|
|
|
2016-07-01 11:15:16 +03:00
|
|
|
PCompositorWidgetParent* AllocPCompositorWidgetParent(const CompositorWidgetInitData& aInitData) override {
|
|
|
|
// Not allowed.
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
bool DeallocPCompositorWidgetParent(PCompositorWidgetParent* aActor) override {
|
|
|
|
// Not allowed.
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-06-15 14:28:10 +03:00
|
|
|
virtual CompositorBridgeParentIPCAllocator* AsCompositorBridgeParentIPCAllocator() override { return this; }
|
|
|
|
|
2016-08-16 18:46:13 +03:00
|
|
|
virtual void UpdatePaintTime(LayerTransactionParent* aLayerTree, const TimeDuration& aPaintTime) override {
|
|
|
|
uint64_t id = aLayerTree->GetId();
|
|
|
|
MOZ_ASSERT(id != 0);
|
|
|
|
|
|
|
|
CompositorBridgeParent::LayerTreeState* state =
|
|
|
|
CompositorBridgeParent::GetIndirectShadowTree(id);
|
|
|
|
if (!state || !state->mParent) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
state->mParent->UpdatePaintTime(aLayerTree, aPaintTime);
|
|
|
|
}
|
|
|
|
|
2015-09-11 16:24:46 +03:00
|
|
|
protected:
|
2016-05-16 09:38:34 +03:00
|
|
|
void OnChannelConnected(int32_t pid) override {
|
|
|
|
mCompositorThreadHolder = CompositorThreadHolder::GetSingleton();
|
|
|
|
}
|
2012-07-18 03:59:45 +04:00
|
|
|
private:
|
2014-04-04 20:27:02 +04:00
|
|
|
// Private destructor, to discourage deletion outside of Release():
|
2016-03-22 21:08:38 +03:00
|
|
|
virtual ~CrossProcessCompositorBridgeParent();
|
2014-04-04 20:27:02 +04:00
|
|
|
|
2012-07-18 03:59:45 +04:00
|
|
|
void DeferredDestroy();
|
|
|
|
|
|
|
|
// There can be many CPCPs, and IPDL-generated code doesn't hold a
|
|
|
|
// reference to top-level actors. So we hold a reference to
|
|
|
|
// ourself. This is released (deferred) in ActorDestroy().
|
2016-03-22 21:08:38 +03:00
|
|
|
RefPtr<CrossProcessCompositorBridgeParent> mSelfRef;
|
2014-07-04 22:04:11 +04:00
|
|
|
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<CompositorThreadHolder> mCompositorThreadHolder;
|
2014-05-23 22:19:00 +04:00
|
|
|
// If true, we should send a RemotePaintIsReady message when the layer transaction
|
|
|
|
// is received
|
|
|
|
bool mNotifyAfterRemotePaint;
|
2015-11-24 04:50:51 +03:00
|
|
|
bool mDestroyCalled;
|
2012-07-18 03:59:45 +04:00
|
|
|
};
|
|
|
|
|
2016-03-22 21:07:08 +03:00
|
|
|
PCompositorBridgeParent*
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::LayerTreeState::CrossProcessPCompositorBridge() const
|
2016-02-29 09:53:14 +03:00
|
|
|
{
|
|
|
|
return mCrossProcessParent;
|
|
|
|
}
|
|
|
|
|
2014-05-29 01:42:14 +04:00
|
|
|
void
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::DidComposite(TimeStamp& aCompositeStart,
|
|
|
|
TimeStamp& aCompositeEnd)
|
2015-09-09 02:14:51 +03:00
|
|
|
{
|
2015-12-02 22:31:17 +03:00
|
|
|
Unused << SendDidComposite(0, mPendingTransaction, aCompositeStart, aCompositeEnd);
|
|
|
|
mPendingTransaction = 0;
|
|
|
|
|
2015-09-09 02:14:51 +03:00
|
|
|
if (mLayerManager) {
|
|
|
|
nsTArray<ImageCompositeNotification> notifications;
|
|
|
|
mLayerManager->ExtractImageCompositeNotifications(¬ifications);
|
|
|
|
if (!notifications.IsEmpty()) {
|
2015-11-02 08:53:26 +03:00
|
|
|
Unused << ImageBridgeParent::NotifyImageComposites(notifications);
|
2015-07-06 06:02:26 +03:00
|
|
|
}
|
|
|
|
}
|
2014-05-29 01:42:14 +04:00
|
|
|
|
2015-01-13 21:26:26 +03:00
|
|
|
MonitorAutoLock lock(*sIndirectLayerTreesLock);
|
2016-02-29 09:53:12 +03:00
|
|
|
ForEachIndirectLayerTree([&] (LayerTreeState* lts, const uint64_t& aLayersId) -> void {
|
|
|
|
if (lts->mCrossProcessParent) {
|
2016-03-22 21:08:38 +03:00
|
|
|
CrossProcessCompositorBridgeParent* cpcp = lts->mCrossProcessParent;
|
2016-02-29 09:53:12 +03:00
|
|
|
cpcp->DidComposite(aLayersId, aCompositeStart, aCompositeEnd);
|
2014-05-29 01:42:14 +04:00
|
|
|
}
|
2016-02-29 09:53:12 +03:00
|
|
|
});
|
2014-05-29 01:42:14 +04:00
|
|
|
}
|
|
|
|
|
2016-02-29 09:53:12 +03:00
|
|
|
void
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::InvalidateRemoteLayers()
|
2016-02-29 09:53:12 +03:00
|
|
|
{
|
|
|
|
MOZ_ASSERT(CompositorLoop() == MessageLoop::current());
|
|
|
|
|
2016-03-22 21:07:08 +03:00
|
|
|
Unused << PCompositorBridgeParent::SendInvalidateLayers(0);
|
2016-02-29 09:53:12 +03:00
|
|
|
|
|
|
|
MonitorAutoLock lock(*sIndirectLayerTreesLock);
|
|
|
|
ForEachIndirectLayerTree([] (LayerTreeState* lts, const uint64_t& aLayersId) -> void {
|
|
|
|
if (lts->mCrossProcessParent) {
|
2016-03-22 21:08:38 +03:00
|
|
|
CrossProcessCompositorBridgeParent* cpcp = lts->mCrossProcessParent;
|
2016-02-29 09:53:12 +03:00
|
|
|
Unused << cpcp->SendInvalidateLayers(aLayersId);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2016-02-29 09:53:15 +03:00
|
|
|
bool
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::ResetCompositor(const nsTArray<LayersBackend>& aBackendHints,
|
|
|
|
TextureFactoryIdentifier* aOutIdentifier)
|
2016-02-29 09:53:15 +03:00
|
|
|
{
|
|
|
|
Maybe<TextureFactoryIdentifier> newIdentifier;
|
|
|
|
{
|
|
|
|
MonitorAutoLock lock(mResetCompositorMonitor);
|
|
|
|
|
2016-05-05 11:45:00 +03:00
|
|
|
CompositorLoop()->PostTask(NewRunnableMethod
|
|
|
|
<StoreCopyPassByConstLRef<nsTArray<LayersBackend>>,
|
|
|
|
Maybe<TextureFactoryIdentifier>*>(this,
|
|
|
|
&CompositorBridgeParent::ResetCompositorTask,
|
|
|
|
aBackendHints,
|
|
|
|
&newIdentifier));
|
2016-02-29 09:53:15 +03:00
|
|
|
|
|
|
|
mResetCompositorMonitor.Wait();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!newIdentifier) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
*aOutIdentifier = newIdentifier.value();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Invoked on the compositor thread. The main thread is waiting on the given
|
|
|
|
// monitor.
|
|
|
|
void
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::ResetCompositorTask(const nsTArray<LayersBackend>& aBackendHints,
|
|
|
|
Maybe<TextureFactoryIdentifier>* aOutNewIdentifier)
|
2016-02-29 09:53:15 +03:00
|
|
|
{
|
|
|
|
// Perform the reset inside a lock, so the main thread can wake up as soon as
|
|
|
|
// possible. We notify child processes (if necessary) outside the lock.
|
|
|
|
Maybe<TextureFactoryIdentifier> newIdentifier;
|
|
|
|
{
|
|
|
|
MonitorAutoLock lock(mResetCompositorMonitor);
|
|
|
|
|
|
|
|
newIdentifier = ResetCompositorImpl(aBackendHints);
|
|
|
|
*aOutNewIdentifier = newIdentifier;
|
|
|
|
|
|
|
|
mResetCompositorMonitor.NotifyAll();
|
|
|
|
}
|
|
|
|
|
|
|
|
// NOTE: |aBackendHints|, and |aOutNewIdentifier| are now all invalid since
|
|
|
|
// they are allocated on ResetCompositor's stack on the main thread, which
|
|
|
|
// is no longer waiting on the lock.
|
|
|
|
|
|
|
|
if (!newIdentifier) {
|
|
|
|
// No compositor change; nothing to do.
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
MonitorAutoLock lock(*sIndirectLayerTreesLock);
|
|
|
|
ForEachIndirectLayerTree([&] (LayerTreeState* lts, uint64_t layersId) -> void {
|
2016-03-22 21:08:38 +03:00
|
|
|
if (CrossProcessCompositorBridgeParent* cpcp = lts->mCrossProcessParent) {
|
2016-02-29 09:53:15 +03:00
|
|
|
Unused << cpcp->SendCompositorUpdated(layersId, newIdentifier.value());
|
2016-03-25 11:35:07 +03:00
|
|
|
|
|
|
|
if (LayerTransactionParent* ltp = lts->mLayerTree) {
|
|
|
|
ltp->AddPendingCompositorUpdate();
|
|
|
|
}
|
|
|
|
lts->mPendingCompositorUpdates++;
|
2016-02-29 09:53:15 +03:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
Maybe<TextureFactoryIdentifier>
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::ResetCompositorImpl(const nsTArray<LayersBackend>& aBackendHints)
|
2016-02-29 09:53:15 +03:00
|
|
|
{
|
|
|
|
if (!mLayerManager) {
|
|
|
|
return Nothing();
|
|
|
|
}
|
|
|
|
|
|
|
|
RefPtr<Compositor> compositor = NewCompositor(aBackendHints);
|
|
|
|
if (!compositor) {
|
|
|
|
return Nothing();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Don't bother changing from basic->basic.
|
|
|
|
if (mCompositor &&
|
|
|
|
mCompositor->GetBackendType() == LayersBackend::LAYERS_BASIC &&
|
|
|
|
compositor->GetBackendType() == LayersBackend::LAYERS_BASIC)
|
|
|
|
{
|
|
|
|
return Nothing();
|
|
|
|
}
|
|
|
|
|
2016-03-25 11:38:55 +03:00
|
|
|
if (mCompositor) {
|
|
|
|
mCompositor->SetInvalid();
|
|
|
|
}
|
2016-02-29 09:53:15 +03:00
|
|
|
mCompositor = compositor;
|
|
|
|
mLayerManager->ChangeCompositor(compositor);
|
|
|
|
|
|
|
|
return Some(compositor->GetTextureFactoryIdentifier());
|
|
|
|
}
|
|
|
|
|
2012-07-18 03:59:45 +04:00
|
|
|
static void
|
2016-07-18 07:24:28 +03:00
|
|
|
OpenCompositor(RefPtr<CrossProcessCompositorBridgeParent> aCompositor,
|
|
|
|
Endpoint<PCompositorBridgeParent>&& aEndpoint)
|
2012-07-18 03:59:45 +04:00
|
|
|
{
|
2016-07-18 07:24:28 +03:00
|
|
|
aCompositor->Bind(Move(aEndpoint));
|
2012-07-18 03:59:45 +04:00
|
|
|
}
|
|
|
|
|
2016-07-18 07:24:28 +03:00
|
|
|
/* static */ bool
|
|
|
|
CompositorBridgeParent::CreateForContent(Endpoint<PCompositorBridgeParent>&& aEndpoint)
|
2012-07-18 03:59:45 +04:00
|
|
|
{
|
2014-07-04 22:04:11 +04:00
|
|
|
gfxPlatform::InitLayersIPC();
|
|
|
|
|
2016-03-22 21:08:38 +03:00
|
|
|
RefPtr<CrossProcessCompositorBridgeParent> cpcp =
|
2016-07-07 04:51:20 +03:00
|
|
|
new CrossProcessCompositorBridgeParent();
|
2014-05-08 19:32:00 +04:00
|
|
|
|
2016-07-18 07:24:28 +03:00
|
|
|
CompositorLoop()->PostTask(NewRunnableFunction(OpenCompositor, cpcp, Move(aEndpoint)));
|
|
|
|
return true;
|
2012-07-18 03:59:45 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2013-07-30 22:03:40 +04:00
|
|
|
UpdateIndirectTree(uint64_t aId, Layer* aRoot, const TargetConfig& aTargetConfig)
|
2012-07-18 03:59:45 +04:00
|
|
|
{
|
2015-01-13 21:26:26 +03:00
|
|
|
MonitorAutoLock lock(*sIndirectLayerTreesLock);
|
2012-07-20 10:48:27 +04:00
|
|
|
sIndirectLayerTrees[aId].mRoot = aRoot;
|
2012-11-22 06:40:57 +04:00
|
|
|
sIndirectLayerTrees[aId].mTargetConfig = aTargetConfig;
|
2012-07-18 03:59:45 +04:00
|
|
|
}
|
|
|
|
|
2016-03-22 21:08:38 +03:00
|
|
|
/* static */ CompositorBridgeParent::LayerTreeState*
|
|
|
|
CompositorBridgeParent::GetIndirectShadowTree(uint64_t aId)
|
2012-07-18 03:59:45 +04:00
|
|
|
{
|
2015-01-13 21:26:26 +03:00
|
|
|
MonitorAutoLock lock(*sIndirectLayerTreesLock);
|
2014-04-22 01:46:50 +04:00
|
|
|
LayerTreeMap::iterator cit = sIndirectLayerTrees.find(aId);
|
2012-07-18 03:59:45 +04:00
|
|
|
if (sIndirectLayerTrees.end() == cit) {
|
2012-07-30 18:20:58 +04:00
|
|
|
return nullptr;
|
2012-07-18 03:59:45 +04:00
|
|
|
}
|
2012-07-20 10:48:27 +04:00
|
|
|
return &cit->second;
|
2012-07-18 03:59:45 +04:00
|
|
|
}
|
|
|
|
|
2016-04-13 00:04:50 +03:00
|
|
|
PTextureParent*
|
|
|
|
CompositorBridgeParent::AllocPTextureParent(const SurfaceDescriptor& aSharedData,
|
|
|
|
const LayersBackend& aLayersBackend,
|
|
|
|
const TextureFlags& aFlags,
|
2016-06-15 14:28:10 +03:00
|
|
|
const uint64_t& aId,
|
|
|
|
const uint64_t& aSerial)
|
2016-04-13 00:04:50 +03:00
|
|
|
{
|
2016-06-15 14:28:10 +03:00
|
|
|
return TextureHost::CreateIPDLActor(this, aSharedData, aLayersBackend, aFlags, aSerial);
|
2016-04-13 00:04:50 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
CompositorBridgeParent::DeallocPTextureParent(PTextureParent* actor)
|
|
|
|
{
|
|
|
|
return TextureHost::DestroyIPDLActor(actor);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
CompositorBridgeParent::AllocShmem(size_t aSize,
|
|
|
|
ipc::SharedMemory::SharedMemoryType aType,
|
|
|
|
ipc::Shmem* aShmem)
|
|
|
|
{
|
|
|
|
return PCompositorBridgeParent::AllocShmem(aSize, aType, aShmem);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
CompositorBridgeParent::AllocUnsafeShmem(size_t aSize,
|
|
|
|
ipc::SharedMemory::SharedMemoryType aType,
|
|
|
|
ipc::Shmem* aShmem)
|
|
|
|
{
|
|
|
|
return PCompositorBridgeParent::AllocUnsafeShmem(aSize, aType, aShmem);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
CompositorBridgeParent::DeallocShmem(ipc::Shmem& aShmem)
|
|
|
|
{
|
|
|
|
PCompositorBridgeParent::DeallocShmem(aShmem);
|
|
|
|
}
|
|
|
|
|
2016-06-15 14:28:10 +03:00
|
|
|
void
|
|
|
|
CompositorBridgeParent::SendAsyncMessage(const InfallibleTArray<AsyncParentMessageData>& aMessage)
|
|
|
|
{
|
|
|
|
Unused << SendParentAsyncMessages(aMessage);
|
|
|
|
}
|
|
|
|
|
2016-04-13 00:04:50 +03:00
|
|
|
bool
|
|
|
|
CompositorBridgeParent::IsSameProcess() const
|
|
|
|
{
|
|
|
|
return OtherPid() == base::GetCurrentProcId();
|
|
|
|
}
|
|
|
|
|
2014-05-23 22:19:00 +04:00
|
|
|
bool
|
2016-03-22 21:08:38 +03:00
|
|
|
CrossProcessCompositorBridgeParent::RecvRequestNotifyAfterRemotePaint()
|
2014-05-23 22:19:00 +04:00
|
|
|
{
|
|
|
|
mNotifyAfterRemotePaint = true;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2012-07-18 03:59:45 +04:00
|
|
|
void
|
2016-03-22 21:08:38 +03:00
|
|
|
CrossProcessCompositorBridgeParent::ActorDestroy(ActorDestroyReason aWhy)
|
2012-07-18 03:59:45 +04:00
|
|
|
{
|
2015-11-24 04:50:51 +03:00
|
|
|
// We must keep this object alive untill the code handling message
|
|
|
|
// reception is finished on this thread.
|
2016-05-05 11:45:00 +03:00
|
|
|
MessageLoop::current()->PostTask(NewRunnableMethod(this, &CrossProcessCompositorBridgeParent::DeferredDestroy));
|
2012-07-18 03:59:45 +04:00
|
|
|
}
|
|
|
|
|
2013-04-24 22:42:40 +04:00
|
|
|
PLayerTransactionParent*
|
2016-03-22 21:08:38 +03:00
|
|
|
CrossProcessCompositorBridgeParent::AllocPLayerTransactionParent(
|
|
|
|
const nsTArray<LayersBackend>&,
|
|
|
|
const uint64_t& aId,
|
|
|
|
TextureFactoryIdentifier* aTextureFactoryIdentifier,
|
|
|
|
bool *aSuccess)
|
2012-07-18 03:59:45 +04:00
|
|
|
{
|
|
|
|
MOZ_ASSERT(aId != 0);
|
|
|
|
|
2015-01-13 21:26:26 +03:00
|
|
|
MonitorAutoLock lock(*sIndirectLayerTreesLock);
|
|
|
|
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::LayerTreeState* state = nullptr;
|
2014-05-12 01:03:00 +04:00
|
|
|
LayerTreeMap::iterator itr = sIndirectLayerTrees.find(aId);
|
|
|
|
if (sIndirectLayerTrees.end() != itr) {
|
|
|
|
state = &itr->second;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (state && state->mLayerManager) {
|
|
|
|
state->mCrossProcessParent = this;
|
|
|
|
LayerManagerComposite* lm = state->mLayerManager;
|
2013-12-09 05:40:59 +04:00
|
|
|
*aTextureFactoryIdentifier = lm->GetCompositor()->GetTextureFactoryIdentifier();
|
2013-08-04 11:46:17 +04:00
|
|
|
*aSuccess = true;
|
2015-04-01 11:40:35 +03:00
|
|
|
LayerTransactionParent* p = new LayerTransactionParent(lm, this, aId);
|
2013-11-27 19:18:38 +04:00
|
|
|
p->AddIPDLReference();
|
2014-05-29 01:42:14 +04:00
|
|
|
sIndirectLayerTrees[aId].mLayerTree = p;
|
2016-03-25 11:35:07 +03:00
|
|
|
p->SetPendingCompositorUpdates(state->mPendingCompositorUpdates);
|
2013-11-27 19:18:38 +04:00
|
|
|
return p;
|
2013-07-12 06:32:09 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_WARNING("Created child without a matching parent?");
|
2013-08-04 11:46:17 +04:00
|
|
|
// XXX: should be false, but that causes us to fail some tests on Mac w/ OMTC.
|
|
|
|
// Bug 900745. change *aSuccess to false to see test failures.
|
|
|
|
*aSuccess = true;
|
2015-04-01 11:40:35 +03:00
|
|
|
LayerTransactionParent* p = new LayerTransactionParent(nullptr, this, aId);
|
2013-11-27 19:18:38 +04:00
|
|
|
p->AddIPDLReference();
|
|
|
|
return p;
|
2012-07-18 03:59:45 +04:00
|
|
|
}
|
Bug 825928: Land layers refactoring. r=jrmuizel,bas,nical,mattwoodrow,roc,nrc,benwa,bjacob,jgilbert,kchen CLOSED TREE
Please contact Bas Schouten <bschouten@mozilla.com>, Nicolas Silva <nsilva@mozilla.com> or Nicholas Cameron <ncameron@mozilla.com> with general questions. Below is a rough list of authors to contact with specific questions.
Authors:
gfx/layers/Compositor.* gfx/layers/Effects.h - Compositor Interface - bas,nrc,nical
gfx/layers/d3d* - D3D9/D3D10 - bas
gfx/layers/ThebesLayer* - ThebesLayers - nrc,bas
gfx/layers/composite/* - CompositeLayers - nrc,nical
gfx/layers/client/* - Client - nrc,nical,bas
gfx/layers/*Image* - nical
gfx/layers/ipc ipc - IPC - nical
gfx/layers/opengl - CompositorOGL - nrc,nical
gfx/2d - bas,nrc
gfx/gl - GLContext - bjacob
dom/* layout/* - DOM - mattwoodrow
2013-04-10 13:20:52 +04:00
|
|
|
|
2012-07-18 03:59:45 +04:00
|
|
|
bool
|
2016-03-22 21:08:38 +03:00
|
|
|
CrossProcessCompositorBridgeParent::DeallocPLayerTransactionParent(PLayerTransactionParent* aLayers)
|
2012-07-18 03:59:45 +04:00
|
|
|
{
|
2013-04-24 22:42:40 +04:00
|
|
|
LayerTransactionParent* slp = static_cast<LayerTransactionParent*>(aLayers);
|
2015-01-13 21:26:26 +03:00
|
|
|
EraseLayerState(slp->GetId());
|
2013-11-27 19:18:38 +04:00
|
|
|
static_cast<LayerTransactionParent*>(aLayers)->ReleaseIPDLReference();
|
2012-07-18 03:59:45 +04:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2013-07-12 06:32:09 +04:00
|
|
|
bool
|
2016-03-22 21:08:38 +03:00
|
|
|
CrossProcessCompositorBridgeParent::RecvNotifyChildCreated(const uint64_t& child)
|
2013-07-12 06:32:09 +04:00
|
|
|
{
|
2015-01-13 21:26:26 +03:00
|
|
|
MonitorAutoLock lock(*sIndirectLayerTreesLock);
|
2014-06-14 11:25:02 +04:00
|
|
|
for (LayerTreeMap::iterator it = sIndirectLayerTrees.begin();
|
|
|
|
it != sIndirectLayerTrees.end(); it++) {
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::LayerTreeState* lts = &it->second;
|
2014-06-14 11:25:02 +04:00
|
|
|
if (lts->mParent && lts->mCrossProcessParent == this) {
|
|
|
|
lts->mParent->NotifyChildCreated(child);
|
|
|
|
return true;
|
|
|
|
}
|
2014-05-12 01:03:00 +04:00
|
|
|
}
|
2014-06-14 11:25:02 +04:00
|
|
|
return false;
|
2013-07-12 06:32:09 +04:00
|
|
|
}
|
|
|
|
|
2012-07-18 03:59:45 +04:00
|
|
|
void
|
2016-03-22 21:08:38 +03:00
|
|
|
CrossProcessCompositorBridgeParent::ShadowLayersUpdated(
|
2013-04-24 22:42:40 +04:00
|
|
|
LayerTransactionParent* aLayerTree,
|
2014-05-29 01:42:14 +04:00
|
|
|
const uint64_t& aTransactionId,
|
2012-07-24 23:01:09 +04:00
|
|
|
const TargetConfig& aTargetConfig,
|
2015-01-29 22:41:55 +03:00
|
|
|
const InfallibleTArray<PluginWindowData>& aPlugins,
|
2013-12-16 09:38:42 +04:00
|
|
|
bool aIsFirstPaint,
|
2014-05-07 01:26:13 +04:00
|
|
|
bool aScheduleComposite,
|
2014-05-31 02:52:43 +04:00
|
|
|
uint32_t aPaintSequenceNumber,
|
2015-08-18 21:27:20 +03:00
|
|
|
bool aIsRepeatTransaction,
|
2016-05-16 21:53:44 +03:00
|
|
|
int32_t /*aPaintSyncId: unused*/,
|
|
|
|
bool aHitTestUpdate)
|
2012-07-18 03:59:45 +04:00
|
|
|
{
|
|
|
|
uint64_t id = aLayerTree->GetId();
|
2014-04-28 06:22:00 +04:00
|
|
|
|
2012-07-18 03:59:45 +04:00
|
|
|
MOZ_ASSERT(id != 0);
|
2014-04-28 06:22:00 +04:00
|
|
|
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::LayerTreeState* state =
|
|
|
|
CompositorBridgeParent::GetIndirectShadowTree(id);
|
2014-05-12 01:03:00 +04:00
|
|
|
if (!state) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
MOZ_ASSERT(state->mParent);
|
|
|
|
state->mParent->ScheduleRotationOnCompositorThread(aTargetConfig, aIsFirstPaint);
|
2014-04-28 06:22:00 +04:00
|
|
|
|
2012-07-18 03:59:45 +04:00
|
|
|
Layer* shadowRoot = aLayerTree->GetRoot();
|
2014-10-23 00:03:18 +04:00
|
|
|
if (shadowRoot) {
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::SetShadowProperties(shadowRoot);
|
2014-10-23 00:03:18 +04:00
|
|
|
}
|
2013-07-30 22:03:40 +04:00
|
|
|
UpdateIndirectTree(id, shadowRoot, aTargetConfig);
|
2012-07-18 03:59:45 +04:00
|
|
|
|
2015-01-29 22:41:55 +03:00
|
|
|
// Cache the plugin data for this remote layer tree
|
|
|
|
state->mPluginData = aPlugins;
|
2015-03-04 16:46:15 +03:00
|
|
|
state->mUpdatedPluginDataAvailable = true;
|
2015-01-29 22:41:55 +03:00
|
|
|
|
2014-05-07 01:26:13 +04:00
|
|
|
state->mParent->NotifyShadowTreeTransaction(id, aIsFirstPaint, aScheduleComposite,
|
2016-05-16 21:53:44 +03:00
|
|
|
aPaintSequenceNumber, aIsRepeatTransaction, aHitTestUpdate);
|
2014-05-23 22:19:00 +04:00
|
|
|
|
|
|
|
// Send the 'remote paint ready' message to the content thread if it has already asked.
|
|
|
|
if(mNotifyAfterRemotePaint) {
|
2015-11-02 08:53:26 +03:00
|
|
|
Unused << SendRemotePaintIsReady();
|
2014-05-23 22:19:00 +04:00
|
|
|
mNotifyAfterRemotePaint = false;
|
|
|
|
}
|
|
|
|
|
2016-07-23 02:36:45 +03:00
|
|
|
if (aLayerTree->ShouldParentObserveEpoch()) {
|
|
|
|
dom::TabParent::ObserveLayerUpdate(id, aLayerTree->GetChildEpoch(), true);
|
2015-02-27 08:30:44 +03:00
|
|
|
}
|
|
|
|
|
2014-05-29 01:42:14 +04:00
|
|
|
aLayerTree->SetPendingTransactionId(aTransactionId);
|
|
|
|
}
|
|
|
|
|
2015-03-04 16:46:15 +03:00
|
|
|
#if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
|
2015-10-06 22:23:24 +03:00
|
|
|
//#define PLUGINS_LOG(...) printf_stderr("CP [%s]: ", __FUNCTION__);
|
|
|
|
// printf_stderr(__VA_ARGS__);
|
|
|
|
// printf_stderr("\n");
|
|
|
|
#define PLUGINS_LOG(...)
|
|
|
|
|
|
|
|
bool
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::UpdatePluginWindowState(uint64_t aId)
|
2015-01-29 22:41:55 +03:00
|
|
|
{
|
2015-10-19 18:38:42 +03:00
|
|
|
MonitorAutoLock lock(*sIndirectLayerTreesLock);
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::LayerTreeState& lts = sIndirectLayerTrees[aId];
|
2015-10-19 18:38:42 +03:00
|
|
|
if (!lts.mParent) {
|
|
|
|
PLUGINS_LOG("[%" PRIu64 "] layer tree compositor parent pointer is null", aId);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2015-10-06 22:23:24 +03:00
|
|
|
// Check if this layer tree has received any shadow layer updates
|
2015-10-06 22:23:24 +03:00
|
|
|
if (!lts.mUpdatedPluginDataAvailable) {
|
2016-03-05 02:56:03 +03:00
|
|
|
PLUGINS_LOG("[%" PRIu64 "] no plugin data", aId);
|
|
|
|
return false;
|
2015-10-06 22:23:24 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// pluginMetricsChanged tracks whether we need to send plugin update
|
|
|
|
// data to the main thread. If we do we'll have to block composition,
|
|
|
|
// which we want to avoid if at all possible.
|
|
|
|
bool pluginMetricsChanged = false;
|
|
|
|
|
|
|
|
// Same layer tree checks
|
|
|
|
if (mLastPluginUpdateLayerTreeId == aId) {
|
|
|
|
// no plugin data and nothing has changed, bail.
|
|
|
|
if (!mCachedPluginData.Length() && !lts.mPluginData.Length()) {
|
|
|
|
PLUGINS_LOG("[%" PRIu64 "] no data, no changes", aId);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mCachedPluginData.Length() == lts.mPluginData.Length()) {
|
|
|
|
// check for plugin data changes
|
|
|
|
for (uint32_t idx = 0; idx < lts.mPluginData.Length(); idx++) {
|
|
|
|
if (!(mCachedPluginData[idx] == lts.mPluginData[idx])) {
|
|
|
|
pluginMetricsChanged = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// array lengths don't match, need to update
|
|
|
|
pluginMetricsChanged = true;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// exchanging layer trees, we need to update
|
|
|
|
pluginMetricsChanged = true;
|
2015-01-29 22:41:55 +03:00
|
|
|
}
|
|
|
|
|
2016-01-12 20:05:58 +03:00
|
|
|
// Check if plugin windows are currently hidden due to scrolling
|
|
|
|
if (mDeferPluginWindows) {
|
|
|
|
PLUGINS_LOG("[%" PRIu64 "] suppressing", aId);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-02-04 18:10:55 +03:00
|
|
|
// If the plugin windows were hidden but now are not, we need to force
|
|
|
|
// update the metrics to make sure they are visible again.
|
|
|
|
if (mPluginWindowsHidden) {
|
|
|
|
PLUGINS_LOG("[%" PRIu64 "] re-showing", aId);
|
|
|
|
mPluginWindowsHidden = false;
|
|
|
|
pluginMetricsChanged = true;
|
|
|
|
}
|
|
|
|
|
2015-10-06 22:23:24 +03:00
|
|
|
if (!lts.mPluginData.Length()) {
|
2016-03-23 01:30:14 +03:00
|
|
|
// Don't hide plugins if the previous remote layer tree didn't contain any.
|
|
|
|
if (!mCachedPluginData.Length()) {
|
|
|
|
PLUGINS_LOG("[%" PRIu64 "] nothing to hide", aId);
|
|
|
|
return false;
|
|
|
|
}
|
2016-04-30 02:20:42 +03:00
|
|
|
|
2016-07-01 11:15:16 +03:00
|
|
|
uintptr_t parentWidget = GetWidget()->GetWidgetKey();
|
2016-04-30 02:20:42 +03:00
|
|
|
|
2015-10-06 22:23:24 +03:00
|
|
|
// We will pass through here in cases where the previous shadow layer
|
|
|
|
// tree contained visible plugins and the new tree does not. All we need
|
|
|
|
// to do here is hide the plugins for the old tree, so don't waste time
|
|
|
|
// calculating clipping.
|
2015-10-06 22:23:24 +03:00
|
|
|
mPluginsLayerOffset = nsIntPoint(0,0);
|
|
|
|
mPluginsLayerVisibleRegion.SetEmpty();
|
2015-11-02 08:53:26 +03:00
|
|
|
Unused << lts.mParent->SendHideAllPlugins(parentWidget);
|
2015-10-06 22:23:24 +03:00
|
|
|
lts.mUpdatedPluginDataAvailable = false;
|
2015-10-06 22:23:24 +03:00
|
|
|
PLUGINS_LOG("[%" PRIu64 "] hide all", aId);
|
|
|
|
} else {
|
|
|
|
// Retrieve the offset and visible region of the layer that hosts
|
2016-03-22 21:08:38 +03:00
|
|
|
// the plugins, CompositorBridgeChild needs these in calculating proper
|
2015-10-06 22:23:24 +03:00
|
|
|
// plugin clipping.
|
|
|
|
LayerTransactionParent* layerTree = lts.mLayerTree;
|
|
|
|
Layer* contentRoot = layerTree->GetRoot();
|
|
|
|
if (contentRoot) {
|
|
|
|
nsIntPoint offset;
|
|
|
|
nsIntRegion visibleRegion;
|
|
|
|
if (contentRoot->GetVisibleRegionRelativeToRootLayer(visibleRegion,
|
|
|
|
&offset)) {
|
|
|
|
// Check to see if these values have changed, if so we need to
|
|
|
|
// update plugin window position within the window.
|
|
|
|
if (!pluginMetricsChanged &&
|
|
|
|
mPluginsLayerVisibleRegion == visibleRegion &&
|
|
|
|
mPluginsLayerOffset == offset) {
|
|
|
|
PLUGINS_LOG("[%" PRIu64 "] no change", aId);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
mPluginsLayerOffset = offset;
|
|
|
|
mPluginsLayerVisibleRegion = visibleRegion;
|
2015-12-03 01:32:55 +03:00
|
|
|
Unused << lts.mParent->SendUpdatePluginConfigurations(
|
|
|
|
LayoutDeviceIntPoint::FromUnknownPoint(offset),
|
|
|
|
LayoutDeviceIntRegion::FromUnknownRegion(visibleRegion),
|
|
|
|
lts.mPluginData);
|
2015-10-06 22:23:24 +03:00
|
|
|
lts.mUpdatedPluginDataAvailable = false;
|
|
|
|
PLUGINS_LOG("[%" PRIu64 "] updated", aId);
|
2015-10-22 01:27:48 +03:00
|
|
|
} else {
|
|
|
|
PLUGINS_LOG("[%" PRIu64 "] no visibility data", aId);
|
|
|
|
return false;
|
2015-10-06 22:23:24 +03:00
|
|
|
}
|
2015-10-22 01:27:48 +03:00
|
|
|
} else {
|
|
|
|
PLUGINS_LOG("[%" PRIu64 "] no content root", aId);
|
|
|
|
return false;
|
2015-10-06 22:23:24 +03:00
|
|
|
}
|
2015-01-29 22:41:55 +03:00
|
|
|
}
|
2015-10-06 22:23:24 +03:00
|
|
|
|
|
|
|
mLastPluginUpdateLayerTreeId = aId;
|
|
|
|
mCachedPluginData = lts.mPluginData;
|
|
|
|
return true;
|
2015-01-29 22:41:55 +03:00
|
|
|
}
|
2016-01-12 20:05:58 +03:00
|
|
|
|
|
|
|
void
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::ScheduleShowAllPluginWindows()
|
2016-01-12 20:05:58 +03:00
|
|
|
{
|
|
|
|
MOZ_ASSERT(CompositorLoop());
|
2016-05-05 11:45:00 +03:00
|
|
|
CompositorLoop()->PostTask(NewRunnableMethod(this, &CompositorBridgeParent::ShowAllPluginWindows));
|
2016-01-12 20:05:58 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::ShowAllPluginWindows()
|
2016-01-12 20:05:58 +03:00
|
|
|
{
|
|
|
|
MOZ_ASSERT(!NS_IsMainThread());
|
|
|
|
mDeferPluginWindows = false;
|
|
|
|
ScheduleComposition();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::ScheduleHideAllPluginWindows()
|
2016-01-12 20:05:58 +03:00
|
|
|
{
|
|
|
|
MOZ_ASSERT(CompositorLoop());
|
2016-05-05 11:45:00 +03:00
|
|
|
CompositorLoop()->PostTask(NewRunnableMethod(this, &CompositorBridgeParent::HideAllPluginWindows));
|
2016-01-12 20:05:58 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent::HideAllPluginWindows()
|
2016-01-12 20:05:58 +03:00
|
|
|
{
|
|
|
|
MOZ_ASSERT(!NS_IsMainThread());
|
|
|
|
// No plugins in the cache implies no plugins to manage
|
|
|
|
// in this content.
|
|
|
|
if (!mCachedPluginData.Length() || mDeferPluginWindows) {
|
|
|
|
return;
|
|
|
|
}
|
2016-04-30 02:20:42 +03:00
|
|
|
|
2016-07-01 11:15:16 +03:00
|
|
|
uintptr_t parentWidget = GetWidget()->GetWidgetKey();
|
2016-04-30 02:20:42 +03:00
|
|
|
|
2016-01-12 20:05:58 +03:00
|
|
|
mDeferPluginWindows = true;
|
2016-02-04 18:10:55 +03:00
|
|
|
mPluginWindowsHidden = true;
|
2016-07-18 11:54:02 +03:00
|
|
|
|
|
|
|
#if defined(XP_WIN)
|
|
|
|
// We will get an async reply that this has happened and then send hide.
|
2016-07-18 11:54:02 +03:00
|
|
|
mWaitForPluginsUntil = TimeStamp::Now() + GetGlobalVsyncRate();
|
2016-07-18 11:54:02 +03:00
|
|
|
Unused << SendCaptureAllPlugins(parentWidget);
|
|
|
|
#else
|
2016-04-30 02:20:42 +03:00
|
|
|
Unused << SendHideAllPlugins(parentWidget);
|
2016-01-12 20:05:58 +03:00
|
|
|
ScheduleComposition();
|
2016-07-18 11:54:02 +03:00
|
|
|
#endif
|
2016-01-12 20:05:58 +03:00
|
|
|
}
|
2015-03-04 16:46:15 +03:00
|
|
|
#endif // #if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
|
2015-01-29 22:41:55 +03:00
|
|
|
|
2016-07-18 11:54:02 +03:00
|
|
|
bool
|
|
|
|
CompositorBridgeParent::RecvAllPluginsCaptured()
|
|
|
|
{
|
|
|
|
#if defined(XP_WIN)
|
2016-07-18 11:54:02 +03:00
|
|
|
mWaitForPluginsUntil = TimeStamp();
|
|
|
|
mHaveBlockedForPlugins = false;
|
2016-07-18 11:54:02 +03:00
|
|
|
ForceComposeToTarget(nullptr);
|
|
|
|
Unused << SendHideAllPlugins(GetWidget()->GetWidgetKey());
|
|
|
|
return true;
|
|
|
|
#else
|
|
|
|
MOZ_ASSERT_UNREACHABLE(
|
|
|
|
"CompositorBridgeParent::RecvAllPluginsCaptured calls unexpected.");
|
|
|
|
return false;
|
|
|
|
#endif
|
|
|
|
}
|
2014-05-29 01:42:14 +04:00
|
|
|
void
|
2016-03-22 21:08:38 +03:00
|
|
|
CrossProcessCompositorBridgeParent::DidComposite(
|
|
|
|
uint64_t aId,
|
|
|
|
TimeStamp& aCompositeStart,
|
|
|
|
TimeStamp& aCompositeEnd)
|
2014-05-29 01:42:14 +04:00
|
|
|
{
|
2015-09-09 02:14:51 +03:00
|
|
|
sIndirectLayerTreesLock->AssertCurrentThreadOwns();
|
2015-12-02 22:31:17 +03:00
|
|
|
if (LayerTransactionParent *layerTree = sIndirectLayerTrees[aId].mLayerTree) {
|
2015-11-02 08:53:26 +03:00
|
|
|
Unused << SendDidComposite(aId, layerTree->GetPendingTransactionId(), aCompositeStart, aCompositeEnd);
|
2015-09-09 02:14:51 +03:00
|
|
|
layerTree->SetPendingTransactionId(0);
|
|
|
|
}
|
2012-07-18 03:59:45 +04:00
|
|
|
}
|
|
|
|
|
2014-03-03 04:59:58 +04:00
|
|
|
void
|
2016-03-22 21:08:38 +03:00
|
|
|
CrossProcessCompositorBridgeParent::ForceComposite(LayerTransactionParent* aLayerTree)
|
2014-03-03 04:59:58 +04:00
|
|
|
{
|
|
|
|
uint64_t id = aLayerTree->GetId();
|
|
|
|
MOZ_ASSERT(id != 0);
|
2016-03-22 21:08:38 +03:00
|
|
|
CompositorBridgeParent* parent;
|
2015-01-13 21:26:26 +03:00
|
|
|
{ // scope lock
|
|
|
|
MonitorAutoLock lock(*sIndirectLayerTreesLock);
|
|
|
|
parent = sIndirectLayerTrees[id].mParent;
|
|
|
|
}
|
2015-01-16 21:06:11 +03:00
|
|
|
if (parent) {
|
|
|
|
parent->ForceComposite(aLayerTree);
|
|
|
|
}
|
2014-03-03 04:59:58 +04:00
|
|
|
}
|
|
|
|
|
2015-02-27 08:30:44 +03:00
|
|
|
void
|
2016-03-22 21:08:38 +03:00
|
|
|
CrossProcessCompositorBridgeParent::NotifyClearCachedResources(LayerTransactionParent* aLayerTree)
|
2015-02-27 08:30:44 +03:00
|
|
|
{
|
|
|
|
uint64_t id = aLayerTree->GetId();
|
|
|
|
MOZ_ASSERT(id != 0);
|
|
|
|
|
2016-07-23 02:36:45 +03:00
|
|
|
dom::TabParent::ObserveLayerUpdate(id, aLayerTree->GetChildEpoch(), false);
|
2015-02-27 08:30:44 +03:00
|
|
|
}
|
|
|
|
|
2014-03-22 01:59:57 +04:00
|
|
|
bool
|
2016-03-22 21:08:38 +03:00
|
|
|
CrossProcessCompositorBridgeParent::SetTestSampleTime(
|
2014-03-22 01:59:57 +04:00
|
|
|
LayerTransactionParent* aLayerTree, const TimeStamp& aTime)
|
|
|
|
{
|
|
|
|
uint64_t id = aLayerTree->GetId();
|
|
|
|
MOZ_ASSERT(id != 0);
|
2016-03-22 21:08:38 +03:00
|
|
|
const CompositorBridgeParent::LayerTreeState* state =
|
|
|
|
CompositorBridgeParent::GetIndirectShadowTree(id);
|
2014-05-12 01:03:00 +04:00
|
|
|
if (!state) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
MOZ_ASSERT(state->mParent);
|
|
|
|
return state->mParent->SetTestSampleTime(aLayerTree, aTime);
|
2014-03-22 01:59:57 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2016-03-22 21:08:38 +03:00
|
|
|
CrossProcessCompositorBridgeParent::LeaveTestMode(LayerTransactionParent* aLayerTree)
|
2014-03-22 01:59:57 +04:00
|
|
|
{
|
|
|
|
uint64_t id = aLayerTree->GetId();
|
|
|
|
MOZ_ASSERT(id != 0);
|
2016-03-22 21:08:38 +03:00
|
|
|
const CompositorBridgeParent::LayerTreeState* state =
|
|
|
|
CompositorBridgeParent::GetIndirectShadowTree(id);
|
2014-05-12 01:03:00 +04:00
|
|
|
if (!state) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
MOZ_ASSERT(state->mParent);
|
|
|
|
state->mParent->LeaveTestMode(aLayerTree);
|
2014-03-22 01:59:57 +04:00
|
|
|
}
|
|
|
|
|
2015-04-21 06:00:33 +03:00
|
|
|
void
|
2016-03-22 21:08:38 +03:00
|
|
|
CrossProcessCompositorBridgeParent::ApplyAsyncProperties(
|
2015-04-21 06:00:33 +03:00
|
|
|
LayerTransactionParent* aLayerTree)
|
|
|
|
{
|
|
|
|
uint64_t id = aLayerTree->GetId();
|
|
|
|
MOZ_ASSERT(id != 0);
|
2016-03-22 21:08:38 +03:00
|
|
|
const CompositorBridgeParent::LayerTreeState* state =
|
|
|
|
CompositorBridgeParent::GetIndirectShadowTree(id);
|
2015-04-21 06:00:33 +03:00
|
|
|
if (!state) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
MOZ_ASSERT(state->mParent);
|
|
|
|
state->mParent->ApplyAsyncProperties(aLayerTree);
|
|
|
|
}
|
|
|
|
|
2015-06-19 15:25:41 +03:00
|
|
|
void
|
2016-03-22 21:08:38 +03:00
|
|
|
CrossProcessCompositorBridgeParent::FlushApzRepaints(const LayerTransactionParent* aLayerTree)
|
2015-06-19 15:25:41 +03:00
|
|
|
{
|
|
|
|
uint64_t id = aLayerTree->GetId();
|
|
|
|
MOZ_ASSERT(id != 0);
|
2016-03-22 21:08:38 +03:00
|
|
|
const CompositorBridgeParent::LayerTreeState* state =
|
|
|
|
CompositorBridgeParent::GetIndirectShadowTree(id);
|
2015-06-19 15:25:41 +03:00
|
|
|
if (!state) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
MOZ_ASSERT(state->mParent);
|
|
|
|
state->mParent->FlushApzRepaints(aLayerTree);
|
|
|
|
}
|
|
|
|
|
2014-05-08 03:56:48 +04:00
|
|
|
void
|
2016-03-22 21:08:38 +03:00
|
|
|
CrossProcessCompositorBridgeParent::GetAPZTestData(
|
|
|
|
const LayerTransactionParent* aLayerTree,
|
|
|
|
APZTestData* aOutData)
|
2014-05-08 03:56:48 +04:00
|
|
|
{
|
|
|
|
uint64_t id = aLayerTree->GetId();
|
|
|
|
MOZ_ASSERT(id != 0);
|
2015-01-13 21:26:26 +03:00
|
|
|
MonitorAutoLock lock(*sIndirectLayerTreesLock);
|
2014-05-08 03:56:48 +04:00
|
|
|
*aOutData = sIndirectLayerTrees[id].mApzTestData;
|
|
|
|
}
|
|
|
|
|
2015-04-14 19:24:32 +03:00
|
|
|
void
|
2016-03-22 21:08:38 +03:00
|
|
|
CrossProcessCompositorBridgeParent::SetConfirmedTargetAPZC(
|
|
|
|
const LayerTransactionParent* aLayerTree,
|
|
|
|
const uint64_t& aInputBlockId,
|
|
|
|
const nsTArray<ScrollableLayerGuid>& aTargets)
|
2015-04-14 19:24:32 +03:00
|
|
|
{
|
|
|
|
uint64_t id = aLayerTree->GetId();
|
|
|
|
MOZ_ASSERT(id != 0);
|
2016-03-22 21:08:38 +03:00
|
|
|
const CompositorBridgeParent::LayerTreeState* state =
|
|
|
|
CompositorBridgeParent::GetIndirectShadowTree(id);
|
2016-01-22 23:28:03 +03:00
|
|
|
if (!state || !state->mParent) {
|
2015-04-15 19:49:28 +03:00
|
|
|
return;
|
2015-04-14 19:24:32 +03:00
|
|
|
}
|
2015-04-15 19:49:28 +03:00
|
|
|
|
|
|
|
state->mParent->SetConfirmedTargetAPZC(aLayerTree, aInputBlockId, aTargets);
|
2015-04-14 19:24:32 +03:00
|
|
|
}
|
2014-05-08 03:56:48 +04:00
|
|
|
|
2014-02-25 02:45:40 +04:00
|
|
|
AsyncCompositionManager*
|
2016-03-22 21:08:38 +03:00
|
|
|
CrossProcessCompositorBridgeParent::GetCompositionManager(LayerTransactionParent* aLayerTree)
|
2014-02-25 02:45:40 +04:00
|
|
|
{
|
|
|
|
uint64_t id = aLayerTree->GetId();
|
2016-03-22 21:08:38 +03:00
|
|
|
const CompositorBridgeParent::LayerTreeState* state =
|
|
|
|
CompositorBridgeParent::GetIndirectShadowTree(id);
|
2014-05-12 01:03:00 +04:00
|
|
|
if (!state) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
MOZ_ASSERT(state->mParent);
|
|
|
|
return state->mParent->GetCompositionManager(aLayerTree);
|
2014-02-25 02:45:40 +04:00
|
|
|
}
|
|
|
|
|
2016-03-25 11:35:07 +03:00
|
|
|
bool
|
|
|
|
CrossProcessCompositorBridgeParent::RecvAcknowledgeCompositorUpdate(const uint64_t& aLayersId)
|
|
|
|
{
|
|
|
|
MonitorAutoLock lock(*sIndirectLayerTreesLock);
|
|
|
|
CompositorBridgeParent::LayerTreeState& state = sIndirectLayerTrees[aLayersId];
|
|
|
|
|
|
|
|
if (LayerTransactionParent* ltp = state.mLayerTree) {
|
|
|
|
ltp->AcknowledgeCompositorUpdate();
|
|
|
|
}
|
|
|
|
MOZ_ASSERT(state.mPendingCompositorUpdates > 0);
|
|
|
|
state.mPendingCompositorUpdates--;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2012-07-18 03:59:45 +04:00
|
|
|
void
|
2016-03-22 21:08:38 +03:00
|
|
|
CrossProcessCompositorBridgeParent::DeferredDestroy()
|
2012-07-18 03:59:45 +04:00
|
|
|
{
|
2014-07-04 22:04:12 +04:00
|
|
|
mCompositorThreadHolder = nullptr;
|
|
|
|
mSelfRef = nullptr;
|
2012-07-18 03:59:45 +04:00
|
|
|
}
|
2012-07-13 23:38:09 +04:00
|
|
|
|
2016-03-22 21:08:38 +03:00
|
|
|
CrossProcessCompositorBridgeParent::~CrossProcessCompositorBridgeParent()
|
2013-02-19 23:27:49 +04:00
|
|
|
{
|
2014-07-04 22:04:11 +04:00
|
|
|
MOZ_ASSERT(XRE_GetIOMessageLoop());
|
2016-07-07 04:51:20 +03:00
|
|
|
MOZ_ASSERT(IToplevelProtocol::GetTransport());
|
2013-02-19 23:27:49 +04:00
|
|
|
}
|
|
|
|
|
2013-06-03 14:14:37 +04:00
|
|
|
IToplevelProtocol*
|
2016-03-22 21:08:38 +03:00
|
|
|
CrossProcessCompositorBridgeParent::CloneToplevel(
|
|
|
|
const InfallibleTArray<mozilla::ipc::ProtocolFdMapping>& aFds,
|
|
|
|
base::ProcessHandle aPeerProcess,
|
|
|
|
mozilla::ipc::ProtocolCloneContext* aCtx)
|
2013-06-03 14:14:37 +04:00
|
|
|
{
|
2016-07-18 07:24:28 +03:00
|
|
|
MOZ_ASSERT_UNREACHABLE("Not supported");
|
2013-06-03 14:14:37 +04:00
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2016-04-13 00:04:50 +03:00
|
|
|
PTextureParent*
|
|
|
|
CrossProcessCompositorBridgeParent::AllocPTextureParent(const SurfaceDescriptor& aSharedData,
|
|
|
|
const LayersBackend& aLayersBackend,
|
|
|
|
const TextureFlags& aFlags,
|
2016-06-15 14:28:10 +03:00
|
|
|
const uint64_t& aId,
|
|
|
|
const uint64_t& aSerial)
|
2016-04-13 00:04:50 +03:00
|
|
|
{
|
|
|
|
CompositorBridgeParent::LayerTreeState* state = nullptr;
|
|
|
|
|
|
|
|
LayerTreeMap::iterator itr = sIndirectLayerTrees.find(aId);
|
|
|
|
if (sIndirectLayerTrees.end() != itr) {
|
|
|
|
state = &itr->second;
|
|
|
|
}
|
|
|
|
|
|
|
|
TextureFlags flags = aFlags;
|
|
|
|
|
|
|
|
if (!state || state->mPendingCompositorUpdates) {
|
|
|
|
// The compositor was recreated, and we're receiving layers updates for a
|
|
|
|
// a layer manager that will soon be discarded or invalidated. We can't
|
|
|
|
// return null because this will mess up deserialization later and we'll
|
|
|
|
// kill the content process. Instead, we signal that the underlying
|
|
|
|
// TextureHost should not attempt to access the compositor.
|
|
|
|
flags |= TextureFlags::INVALID_COMPOSITOR;
|
|
|
|
} else if (state->mLayerManager && state->mLayerManager->GetCompositor() &&
|
|
|
|
aLayersBackend != state->mLayerManager->GetCompositor()->GetBackendType()) {
|
|
|
|
gfxDevCrash(gfx::LogReason::PAllocTextureBackendMismatch) << "Texture backend is wrong";
|
|
|
|
}
|
|
|
|
|
2016-06-15 14:28:10 +03:00
|
|
|
return TextureHost::CreateIPDLActor(this, aSharedData, aLayersBackend, aFlags, aSerial);
|
2016-04-13 00:04:50 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
CrossProcessCompositorBridgeParent::DeallocPTextureParent(PTextureParent* actor)
|
|
|
|
{
|
|
|
|
return TextureHost::DestroyIPDLActor(actor);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
CrossProcessCompositorBridgeParent::AllocShmem(size_t aSize,
|
|
|
|
ipc::SharedMemory::SharedMemoryType aType,
|
|
|
|
ipc::Shmem* aShmem)
|
|
|
|
{
|
|
|
|
return PCompositorBridgeParent::AllocShmem(aSize, aType, aShmem);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
CrossProcessCompositorBridgeParent::AllocUnsafeShmem(size_t aSize,
|
|
|
|
ipc::SharedMemory::SharedMemoryType aType,
|
|
|
|
ipc::Shmem* aShmem)
|
|
|
|
{
|
|
|
|
return PCompositorBridgeParent::AllocUnsafeShmem(aSize, aType, aShmem);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
CrossProcessCompositorBridgeParent::DeallocShmem(ipc::Shmem& aShmem)
|
|
|
|
{
|
|
|
|
PCompositorBridgeParent::DeallocShmem(aShmem);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
CrossProcessCompositorBridgeParent::IsSameProcess() const
|
|
|
|
{
|
|
|
|
return OtherPid() == base::GetCurrentProcId();
|
|
|
|
}
|
|
|
|
|
2011-12-16 00:07:19 +04:00
|
|
|
} // namespace layers
|
|
|
|
} // namespace mozilla
|