зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1592150 - Move a step in the NativeLayerCA swap chain from mSurfaces to a new field called mFrontSurface. r=jrmuizel
This gives us easy access to a surface that has valid content. In the next patch, we will use this surface to copy valid content from. Differential Revision: https://phabricator.services.mozilla.com/D51759 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
1df9c87853
Коммит
334a48fd7d
|
@ -148,22 +148,25 @@ class NativeLayerCA : public NativeLayer {
|
|||
// Each IOSurface is initially created inside NextSurface.
|
||||
// The surface stays alive until the recycling mechanism in NextSurface
|
||||
// determines it is no longer needed (because the swap chain has grown too
|
||||
// long) or until the layer is destroyed. During the surface's lifetime, it
|
||||
// will continuously move through the fields mInProgressSurface,
|
||||
// mReadySurface, and back to front through the mSurfaces queue:
|
||||
// long) or until the layer is destroyed.
|
||||
// During the surface's lifetime, it will continuously move through the fields
|
||||
// mInProgressSurface, mReadySurface, mFrontSurface, and back to front through
|
||||
// the mSurfaces queue:
|
||||
//
|
||||
// mSurfaces.front()
|
||||
// ------[NextSurface()]-----> mInProgressSurface
|
||||
// --[NotifySurfaceReady()]--> mReadySurface
|
||||
// ----[ApplyChanges()]------> mFrontSurface
|
||||
// ----[ApplyChanges()]------> mSurfaces.back() --> .... -->
|
||||
// mSurfaces.front()
|
||||
//
|
||||
// We mark an IOSurface as "in use" as long as it is either in
|
||||
// mInProgressSurface or in mReadySurface. When it is in the mSurfaces queue,
|
||||
// it is not marked as "in use" by us - but it can be "in use" by the window
|
||||
// server. Consequently, IOSurfaceIsInUse on a surface from mSurfaces reflects
|
||||
// whether the window server is still reading from the surface, and we can use
|
||||
// this indicator to decide when to recycle the surface.
|
||||
// mInProgressSurface or in mReadySurface. When it is in mFrontSurface or in
|
||||
// the mSurfaces queue, it is not marked as "in use" by us - but it can be "in
|
||||
// use" by the window server. Consequently, IOSurfaceIsInUse on a surface from
|
||||
// mSurfaces reflects whether the window server is still reading from the
|
||||
// surface, and we can use this indicator to decide when to recycle the
|
||||
// surface.
|
||||
//
|
||||
// Users of NativeLayerCA normally proceed in this order:
|
||||
// 1. Begin a frame by calling NextSurface to get the surface.
|
||||
|
@ -203,9 +206,14 @@ class NativeLayerCA : public NativeLayer {
|
|||
// Both mInProgressSurface and mReadySurface can be Some() at the same time.
|
||||
Maybe<SurfaceWithInvalidRegion> mReadySurface;
|
||||
|
||||
// The queue of surfaces which make up our "swap chain".
|
||||
// The surface that the most recent call to ApplyChanges set on the CALayer.
|
||||
// Will be Some() after the first sequence of NextSurface, NotifySurfaceReady,
|
||||
// ApplyChanges calls, for the rest of the layer's life time.
|
||||
Maybe<SurfaceWithInvalidRegion> mFrontSurface;
|
||||
|
||||
// The queue of surfaces which make up the rest of our "swap chain".
|
||||
// mSurfaces.front() is the next surface we'll attempt to use.
|
||||
// mSurfaces.back() is the one we submitted most recently.
|
||||
// mSurfaces.back() is the one that was used most recently.
|
||||
std::deque<SurfaceWithInvalidRegion> mSurfaces;
|
||||
|
||||
// Non-null between calls to NextSurfaceAsDrawTarget and NotifySurfaceReady.
|
||||
|
|
|
@ -239,6 +239,9 @@ void NativeLayerCA::InvalidateRegionThroughoutSwapchain(const MutexAutoLock&,
|
|||
if (mReadySurface) {
|
||||
mReadySurface->mInvalidRegion.OrWith(r);
|
||||
}
|
||||
if (mFrontSurface) {
|
||||
mFrontSurface->mInvalidRegion.OrWith(r);
|
||||
}
|
||||
for (auto& surf : mSurfaces) {
|
||||
surf.mInvalidRegion.OrWith(r);
|
||||
}
|
||||
|
@ -465,7 +468,13 @@ void NativeLayerCA::ApplyChanges() {
|
|||
if (mReadySurface) {
|
||||
mContentCALayer.contents = (id)mReadySurface->mSurface.get();
|
||||
IOSurfaceDecrementUseCount(mReadySurface->mSurface.get());
|
||||
mSurfaces.push_back(*mReadySurface);
|
||||
|
||||
if (mFrontSurface) {
|
||||
mSurfaces.push_back(*mFrontSurface);
|
||||
mFrontSurface = Nothing();
|
||||
}
|
||||
|
||||
mFrontSurface = Some(*mReadySurface);
|
||||
mReadySurface = Nothing();
|
||||
}
|
||||
}
|
||||
|
@ -476,8 +485,8 @@ std::vector<NativeLayerCA::SurfaceWithInvalidRegion> NativeLayerCA::RemoveExcess
|
|||
std::vector<SurfaceWithInvalidRegion> usedSurfaces;
|
||||
std::vector<SurfaceWithInvalidRegion> unusedSurfaces;
|
||||
|
||||
// Separate mSurfaces into used and unused surfaces, leaving 2 surfaces behind.
|
||||
while (mSurfaces.size() > 2) {
|
||||
// Separate mSurfaces into used and unused surfaces, leaving 1 surface behind.
|
||||
while (mSurfaces.size() > 1) {
|
||||
auto surf = std::move(mSurfaces.front());
|
||||
mSurfaces.pop_front();
|
||||
if (IOSurfaceIsInUse(surf.mSurface.get())) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче