зеркало из https://github.com/mozilla/gecko-dev.git
Backed out 4 changesets (bug 1594950) for turning bug 1405083 into permafail.
Backed out changeset 684a87e91d94 (bug 1594950) Backed out changeset adea6912c3a3 (bug 1594950) Backed out changeset aea7108204e9 (bug 1594950) Backed out changeset 15baea8520de (bug 1594950)
This commit is contained in:
Родитель
e57be9d2f3
Коммит
1d71e9f510
|
@ -33,8 +33,7 @@ class NativeLayerRoot {
|
|||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(NativeLayerRoot)
|
||||
|
||||
virtual already_AddRefed<NativeLayer> CreateLayer(const gfx::IntSize& aSize,
|
||||
bool aIsOpaque) = 0;
|
||||
virtual already_AddRefed<NativeLayer> CreateLayer() = 0;
|
||||
virtual void AppendLayer(NativeLayer* aLayer) = 0;
|
||||
virtual void RemoveLayer(NativeLayer* aLayer) = 0;
|
||||
virtual void SetLayers(const nsTArray<RefPtr<NativeLayer>>& aLayers) = 0;
|
||||
|
@ -67,17 +66,16 @@ class NativeLayer {
|
|||
|
||||
virtual NativeLayerCA* AsNativeLayerCA() { return nullptr; }
|
||||
|
||||
// The size and opaqueness of a layer are supplied during layer creation and
|
||||
// never change.
|
||||
virtual gfx::IntSize GetSize() = 0;
|
||||
virtual bool IsOpaque() = 0;
|
||||
|
||||
// The location of the layer, in integer device pixels.
|
||||
virtual void SetPosition(const gfx::IntPoint& aPosition) = 0;
|
||||
virtual gfx::IntPoint GetPosition() = 0;
|
||||
|
||||
// The location and size of the layer, in integer device pixels. This also
|
||||
// determines the size of the surface that should be returned from the next
|
||||
// call to NextSurface.
|
||||
virtual void SetRect(const gfx::IntRect& aRect) = 0;
|
||||
virtual gfx::IntRect GetRect() = 0;
|
||||
|
||||
// Set whether the layer is fully opaque.
|
||||
virtual void SetIsOpaque(bool aIsOpaque) = 0;
|
||||
virtual bool IsOpaque() = 0;
|
||||
|
||||
// Set an optional clip rect on the layer. The clip rect is in the same
|
||||
// coordinate space as the layer rect.
|
||||
virtual void SetClipRect(const Maybe<gfx::IntRect>& aClipRect) = 0;
|
||||
|
@ -88,18 +86,23 @@ class NativeLayer {
|
|||
virtual void SetSurfaceIsFlipped(bool aIsFlipped) = 0;
|
||||
virtual bool SurfaceIsFlipped() = 0;
|
||||
|
||||
// Returns a DrawTarget. The size of the DrawTarget will be the same as the
|
||||
// size of this layer. The caller should draw to that DrawTarget, then drop
|
||||
// its reference to the DrawTarget, and then call NotifySurfaceReady(). It can
|
||||
// limit its drawing to CurrentSurfaceInvalidRegion() (which is in the
|
||||
// DrawTarget's device space). After a call to NextSurface*, NextSurface* must
|
||||
// not be called again until after NotifySurfaceReady has been called. Can be
|
||||
// called on any thread. When used from multiple threads, callers need to make
|
||||
// sure that they still only call NextSurface* and NotifySurfaceReady
|
||||
// alternatingly and not in any other order.
|
||||
// aUpdateRegion must not extend beyond the layer size.
|
||||
// Invalidates the specified region in all surfaces that are tracked by this
|
||||
// layer.
|
||||
virtual void InvalidateRegionThroughoutSwapchain(
|
||||
const gfx::IntRegion& aRegion) = 0;
|
||||
|
||||
// Returns a DrawTarget. The size of the DrawTarget will be the size of the
|
||||
// rect that has been passed to SetRect. The caller should draw to that
|
||||
// DrawTarget, then drop its reference to the DrawTarget, and then call
|
||||
// NotifySurfaceReady(). It can limit its drawing to
|
||||
// CurrentSurfaceInvalidRegion() (which is in the DrawTarget's device space).
|
||||
// After a call to NextSurface*, NextSurface* must not be called again until
|
||||
// after NotifySurfaceReady has been called. Can be called on any thread. When
|
||||
// used from multiple threads, callers need to make sure that they still only
|
||||
// call NextSurface and NotifySurfaceReady alternatingly and not in any other
|
||||
// order.
|
||||
virtual RefPtr<gfx::DrawTarget> NextSurfaceAsDrawTarget(
|
||||
const gfx::IntRegion& aUpdateRegion, gfx::BackendType aBackendType) = 0;
|
||||
gfx::BackendType aBackendType) = 0;
|
||||
|
||||
// Set the GLContext to use for the MozFramebuffer that are returned from
|
||||
// NextSurfaceAsFramebuffer. If changed to a different value, all
|
||||
|
@ -112,10 +115,10 @@ class NativeLayer {
|
|||
|
||||
// Must only be called if a non-null GLContext is set on this layer.
|
||||
// Returns a GLuint for a framebuffer that can be used for drawing to the
|
||||
// surface. The size of the framebuffer will be the same as the size of this
|
||||
// layer. If aNeedsDepth is true, the framebuffer is created with a depth
|
||||
// buffer. The caller should draw to the framebuffer, unbind it, and then call
|
||||
// NotifySurfaceReady(). It can limit its drawing to
|
||||
// surface. The size of the framebuffer will be the size of the rect that has
|
||||
// been passed to SetRect. If aNeedsDepth is true, the framebuffer is created
|
||||
// with a depth buffer. The caller should draw to the framebuffer, unbind
|
||||
// it, and then call NotifySurfaceReady(). It can limit its drawing to
|
||||
// CurrentSurfaceInvalidRegion() (which is in the framebuffer's device space,
|
||||
// possibly "upside down" if SurfaceIsFlipped()). The framebuffer will be
|
||||
// created using the GLContext that was set on this layer with a call to
|
||||
|
@ -127,17 +130,15 @@ class NativeLayer {
|
|||
// called on any thread. When used from multiple threads, callers need to make
|
||||
// sure that they still only call NextSurface and NotifySurfaceReady
|
||||
// alternatingly and not in any other order.
|
||||
// aUpdateRegion must not extend beyond the layer size.
|
||||
virtual Maybe<GLuint> NextSurfaceAsFramebuffer(
|
||||
const gfx::IntRegion& aUpdateRegion, bool aNeedsDepth) = 0;
|
||||
virtual Maybe<GLuint> NextSurfaceAsFramebuffer(bool aNeedsDepth) = 0;
|
||||
|
||||
// The invalid region of the surface that has been returned from the most
|
||||
// recent call to NextSurface*. Newly-created surfaces are entirely invalid.
|
||||
// For surfaces that have been used before, the invalid region is the union of
|
||||
// all invalid regions that have been passed to NextSurface* since the last
|
||||
// time that NotifySurfaceReady was called for this surface. Can only be
|
||||
// called between calls to NextSurface* and NotifySurfaceReady. Can be called
|
||||
// on any thread.
|
||||
// all invalid regions that have been passed to
|
||||
// InvalidateRegionThroughoutSwapchain since the last time that
|
||||
// NotifySurfaceReady was called for this surface. Can only be called between
|
||||
// calls to NextSurface* and NotifySurfaceReady. Can be called on any thread.
|
||||
virtual gfx::IntRegion CurrentSurfaceInvalidRegion() = 0;
|
||||
|
||||
// Indicates that the surface which has been returned from the most recent
|
||||
|
|
|
@ -34,6 +34,17 @@ class MozFramebuffer;
|
|||
|
||||
namespace layers {
|
||||
|
||||
class IOSurfaceRegistry {
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(IOSurfaceRegistry)
|
||||
|
||||
virtual void RegisterSurface(CFTypeRefPtr<IOSurfaceRef> aSurface) = 0;
|
||||
virtual void UnregisterSurface(CFTypeRefPtr<IOSurfaceRef> aSurface) = 0;
|
||||
|
||||
protected:
|
||||
virtual ~IOSurfaceRegistry() {}
|
||||
};
|
||||
|
||||
// NativeLayerRootCA is the CoreAnimation implementation of the NativeLayerRoot
|
||||
// interface. A NativeLayerRootCA is created by the widget around an existing
|
||||
// CALayer with a call to CreateForCALayer.
|
||||
|
@ -52,8 +63,7 @@ class NativeLayerRootCA : public NativeLayerRoot {
|
|||
void SetBackingScale(float aBackingScale);
|
||||
|
||||
// Overridden methods
|
||||
already_AddRefed<NativeLayer> CreateLayer(const gfx::IntSize& aSize,
|
||||
bool aIsOpaque) override;
|
||||
already_AddRefed<NativeLayer> CreateLayer() override;
|
||||
void AppendLayer(NativeLayer* aLayer) override;
|
||||
void RemoveLayer(NativeLayer* aLayer) override;
|
||||
void SetLayers(const nsTArray<RefPtr<NativeLayer>>& aLayers) override;
|
||||
|
@ -80,38 +90,62 @@ class NativeLayerRootCA : public NativeLayerRoot {
|
|||
// finished, NotifySurfaceReady marks the surface as ready. This surface is
|
||||
// committed to the layer during the next call to ApplyChanges().
|
||||
// The swap chain keeps track of invalid areas within the surfaces.
|
||||
//
|
||||
// Creation and destruction of IOSurface objects is broadcast to an optional
|
||||
// "surface registry" so that associated objects such as framebuffer objects
|
||||
// don't need to be recreated on every frame: Instead, the surface registry can
|
||||
// maintain one object per IOSurface in this layer's swap chain, and those
|
||||
// objects will be reused in different frames as the layer cycles through the
|
||||
// surfaces in its swap chain.
|
||||
class NativeLayerCA : public NativeLayer {
|
||||
public:
|
||||
virtual NativeLayerCA* AsNativeLayerCA() override { return this; }
|
||||
|
||||
// Overridden methods
|
||||
gfx::IntSize GetSize() override;
|
||||
void SetPosition(const gfx::IntPoint& aPosition) override;
|
||||
gfx::IntPoint GetPosition() override;
|
||||
void SetRect(const gfx::IntRect& aRect) override;
|
||||
gfx::IntRect GetRect() override;
|
||||
void InvalidateRegionThroughoutSwapchain(
|
||||
const gfx::IntRegion& aRegion) override;
|
||||
RefPtr<gfx::DrawTarget> NextSurfaceAsDrawTarget(
|
||||
const gfx::IntRegion& aUpdateRegion,
|
||||
gfx::BackendType aBackendType) override;
|
||||
void SetGLContext(gl::GLContext* aGLContext) override;
|
||||
gl::GLContext* GetGLContext() override;
|
||||
Maybe<GLuint> NextSurfaceAsFramebuffer(const gfx::IntRegion& aUpdateRegion,
|
||||
bool aNeedsDepth) override;
|
||||
Maybe<GLuint> NextSurfaceAsFramebuffer(bool aNeedsDepth) override;
|
||||
gfx::IntRegion CurrentSurfaceInvalidRegion() override;
|
||||
void NotifySurfaceReady() override;
|
||||
void SetIsOpaque(bool aIsOpaque) override;
|
||||
bool IsOpaque() override;
|
||||
void SetClipRect(const Maybe<gfx::IntRect>& aClipRect) override;
|
||||
Maybe<gfx::IntRect> ClipRect() override;
|
||||
void SetSurfaceIsFlipped(bool aIsFlipped) override;
|
||||
bool SurfaceIsFlipped() override;
|
||||
|
||||
// Consumers may provide an object that implements the IOSurfaceRegistry
|
||||
// interface.
|
||||
// The registry's methods, Register/UnregisterSurface, will be called
|
||||
// synchronously during calls to NextSurface(), SetSurfaceRegistry(), and the
|
||||
// NativeLayer destructor, on the thread that those things happen to run on.
|
||||
// If this layer already owns surfaces when SetSurfaceRegistry gets called
|
||||
// with a non-null surface registry, those surfaces will immediately
|
||||
// (synchronously) be registered with that registry. If the current surface
|
||||
// registry is unset (via a call to SetSurfaceRegistry with a different value,
|
||||
// such as null), and the NativeLayer still owns surfaces, then those surfaces
|
||||
// will immediately be unregistered.
|
||||
// Since NativeLayer objects are reference counted and can be used from
|
||||
// different threads, it is recommended to call SetSurfaceRegistry(nullptr)
|
||||
// before destroying the NativeLayer so that the UnregisterSurface calls
|
||||
// happen at a deterministic time and on the right thread.
|
||||
void SetSurfaceRegistry(RefPtr<IOSurfaceRegistry> aSurfaceRegistry);
|
||||
RefPtr<IOSurfaceRegistry> GetSurfaceRegistry();
|
||||
|
||||
protected:
|
||||
friend class NativeLayerRootCA;
|
||||
|
||||
NativeLayerCA(const gfx::IntSize& aSize, bool aIsOpaque);
|
||||
NativeLayerCA();
|
||||
~NativeLayerCA() override;
|
||||
|
||||
// Returns an IOSurface that can be drawn to. The size of the IOSurface will
|
||||
// be the same as the size of this layer.
|
||||
// be the size of the rect that has been passed to SetRect.
|
||||
// The returned surface is guaranteed to be not in use by the window server.
|
||||
// After a call to NextSurface, NextSurface must not be called again until
|
||||
// after NotifySurfaceReady has been called. Can be called on any thread. When
|
||||
|
@ -125,11 +159,6 @@ class NativeLayerCA : public NativeLayer {
|
|||
void ApplyChanges();
|
||||
void SetBackingScale(float aBackingScale);
|
||||
|
||||
// Invalidates the specified region in all surfaces that are tracked by this
|
||||
// layer.
|
||||
void InvalidateRegionThroughoutSwapchain(const MutexAutoLock&,
|
||||
const gfx::IntRegion& aRegion);
|
||||
|
||||
GLuint GetOrCreateFramebufferForSurface(const MutexAutoLock&,
|
||||
CFTypeRefPtr<IOSurfaceRef> aSurface,
|
||||
bool aNeedsDepth);
|
||||
|
@ -137,6 +166,7 @@ class NativeLayerCA : public NativeLayer {
|
|||
struct SurfaceWithInvalidRegion {
|
||||
CFTypeRefPtr<IOSurfaceRef> mSurface;
|
||||
gfx::IntRegion mInvalidRegion;
|
||||
gfx::IntSize mSize;
|
||||
};
|
||||
|
||||
std::vector<SurfaceWithInvalidRegion> RemoveExcessUnusedSurfaces(
|
||||
|
@ -145,12 +175,16 @@ class NativeLayerCA : public NativeLayer {
|
|||
// Controls access to all fields of this class.
|
||||
Mutex mMutex;
|
||||
|
||||
RefPtr<IOSurfaceRegistry> mSurfaceRegistry; // can be null
|
||||
|
||||
// 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:
|
||||
// determines it is no longer needed, for example because the layer size
|
||||
// changed or 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:
|
||||
//
|
||||
// mSurfaces.front()
|
||||
// ------[NextSurface()]-----> mInProgressSurface
|
||||
|
@ -217,7 +251,7 @@ class NativeLayerCA : public NativeLayer {
|
|||
mFramebuffers;
|
||||
|
||||
gfx::IntPoint mPosition;
|
||||
const gfx::IntSize mSize;
|
||||
gfx::IntSize mSize;
|
||||
Maybe<gfx::IntRect> mClipRect;
|
||||
|
||||
// Lazily initialized by first call to ApplyChanges. mWrappingLayer is the
|
||||
|
@ -229,10 +263,10 @@ class NativeLayerCA : public NativeLayer {
|
|||
|
||||
float mBackingScale = 1.0f;
|
||||
bool mSurfaceIsFlipped = false;
|
||||
const bool mIsOpaque = false;
|
||||
bool mMutatedBackingScale = false;
|
||||
bool mMutatedSurfaceIsFlipped = false;
|
||||
bool mIsOpaque = false;
|
||||
bool mMutatedPosition = false;
|
||||
bool mMutatedSize = false;
|
||||
bool mMutatedIsOpaque = false;
|
||||
bool mMutatedClipRect = false;
|
||||
};
|
||||
|
||||
|
|
|
@ -54,8 +54,8 @@ NativeLayerRootCA::~NativeLayerRootCA() {
|
|||
[mRootCALayer release];
|
||||
}
|
||||
|
||||
already_AddRefed<NativeLayer> NativeLayerRootCA::CreateLayer(const IntSize& aSize, bool aIsOpaque) {
|
||||
RefPtr<NativeLayer> layer = new NativeLayerCA(aSize, aIsOpaque);
|
||||
already_AddRefed<NativeLayer> NativeLayerRootCA::CreateLayer() {
|
||||
RefPtr<NativeLayer> layer = new NativeLayerCA();
|
||||
return layer.forget();
|
||||
}
|
||||
|
||||
|
@ -135,10 +135,11 @@ void NativeLayerRootCA::SetBackingScale(float aBackingScale) {
|
|||
}
|
||||
}
|
||||
|
||||
NativeLayerCA::NativeLayerCA(const IntSize& aSize, bool aIsOpaque)
|
||||
: mMutex("NativeLayerCA"), mSize(aSize), mIsOpaque(aIsOpaque) {}
|
||||
NativeLayerCA::NativeLayerCA() : mMutex("NativeLayerCA") {}
|
||||
|
||||
NativeLayerCA::~NativeLayerCA() {
|
||||
SetSurfaceRegistry(nullptr); // or maybe MOZ_RELEASE_ASSERT(!mSurfaceRegistry) would be better?
|
||||
|
||||
if (mInProgressLockedIOSurface) {
|
||||
mInProgressLockedIOSurface->Unlock(false);
|
||||
mInProgressLockedIOSurface = nullptr;
|
||||
|
@ -154,12 +155,46 @@ NativeLayerCA::~NativeLayerCA() {
|
|||
[mWrappingCALayer release];
|
||||
}
|
||||
|
||||
void NativeLayerCA::SetSurfaceRegistry(RefPtr<IOSurfaceRegistry> aSurfaceRegistry) {
|
||||
MutexAutoLock lock(mMutex);
|
||||
|
||||
if (mSurfaceRegistry) {
|
||||
for (auto surf : mSurfaces) {
|
||||
mSurfaceRegistry->UnregisterSurface(surf.mSurface);
|
||||
}
|
||||
if (mInProgressSurface) {
|
||||
mSurfaceRegistry->UnregisterSurface(mInProgressSurface->mSurface);
|
||||
}
|
||||
if (mReadySurface) {
|
||||
mSurfaceRegistry->UnregisterSurface(mReadySurface->mSurface);
|
||||
}
|
||||
}
|
||||
mSurfaceRegistry = aSurfaceRegistry;
|
||||
if (mSurfaceRegistry) {
|
||||
for (auto surf : mSurfaces) {
|
||||
mSurfaceRegistry->RegisterSurface(surf.mSurface);
|
||||
}
|
||||
if (mInProgressSurface) {
|
||||
mSurfaceRegistry->RegisterSurface(mInProgressSurface->mSurface);
|
||||
}
|
||||
if (mReadySurface) {
|
||||
mSurfaceRegistry->RegisterSurface(mReadySurface->mSurface);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RefPtr<IOSurfaceRegistry> NativeLayerCA::GetSurfaceRegistry() {
|
||||
MutexAutoLock lock(mMutex);
|
||||
|
||||
return mSurfaceRegistry;
|
||||
}
|
||||
|
||||
void NativeLayerCA::SetSurfaceIsFlipped(bool aIsFlipped) {
|
||||
MutexAutoLock lock(mMutex);
|
||||
|
||||
if (aIsFlipped != mSurfaceIsFlipped) {
|
||||
mSurfaceIsFlipped = aIsFlipped;
|
||||
mMutatedSurfaceIsFlipped = true;
|
||||
mMutatedSize = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -169,22 +204,17 @@ bool NativeLayerCA::SurfaceIsFlipped() {
|
|||
return mSurfaceIsFlipped;
|
||||
}
|
||||
|
||||
IntSize NativeLayerCA::GetSize() {
|
||||
MutexAutoLock lock(mMutex);
|
||||
return mSize;
|
||||
}
|
||||
void NativeLayerCA::SetPosition(const IntPoint& aPosition) {
|
||||
void NativeLayerCA::SetRect(const IntRect& aRect) {
|
||||
MutexAutoLock lock(mMutex);
|
||||
|
||||
if (aPosition != mPosition) {
|
||||
mPosition = aPosition;
|
||||
if (aRect.TopLeft() != mPosition) {
|
||||
mPosition = aRect.TopLeft();
|
||||
mMutatedPosition = true;
|
||||
}
|
||||
}
|
||||
|
||||
IntPoint NativeLayerCA::GetPosition() {
|
||||
MutexAutoLock lock(mMutex);
|
||||
return mPosition;
|
||||
if (aRect.Size() != mSize) {
|
||||
mSize = aRect.Size();
|
||||
mMutatedSize = true;
|
||||
}
|
||||
}
|
||||
|
||||
IntRect NativeLayerCA::GetRect() {
|
||||
|
@ -197,7 +227,18 @@ void NativeLayerCA::SetBackingScale(float aBackingScale) {
|
|||
|
||||
if (aBackingScale != mBackingScale) {
|
||||
mBackingScale = aBackingScale;
|
||||
mMutatedBackingScale = true;
|
||||
mMutatedClipRect = true;
|
||||
mMutatedPosition = true;
|
||||
mMutatedSize = true;
|
||||
}
|
||||
}
|
||||
|
||||
void NativeLayerCA::SetIsOpaque(bool aIsOpaque) {
|
||||
MutexAutoLock lock(mMutex);
|
||||
|
||||
if (aIsOpaque != mIsOpaque) {
|
||||
mIsOpaque = aIsOpaque;
|
||||
mMutatedIsOpaque = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -230,9 +271,11 @@ IntRegion NativeLayerCA::CurrentSurfaceInvalidRegion() {
|
|||
return mInProgressSurface->mInvalidRegion;
|
||||
}
|
||||
|
||||
void NativeLayerCA::InvalidateRegionThroughoutSwapchain(const MutexAutoLock&,
|
||||
const IntRegion& aRegion) {
|
||||
void NativeLayerCA::InvalidateRegionThroughoutSwapchain(const IntRegion& aRegion) {
|
||||
MutexAutoLock lock(mMutex);
|
||||
|
||||
IntRegion r = aRegion;
|
||||
r.AndWith(IntRect(IntPoint(0, 0), mSize));
|
||||
if (mInProgressSurface) {
|
||||
mInProgressSurface->mInvalidRegion.OrWith(r);
|
||||
}
|
||||
|
@ -245,9 +288,10 @@ void NativeLayerCA::InvalidateRegionThroughoutSwapchain(const MutexAutoLock&,
|
|||
}
|
||||
|
||||
CFTypeRefPtr<IOSurfaceRef> NativeLayerCA::NextSurface(const MutexAutoLock& aLock) {
|
||||
if (mSize.IsEmpty()) {
|
||||
NSLog(@"NextSurface returning nullptr because of invalid mSize (%d, %d).", mSize.width,
|
||||
mSize.height);
|
||||
IntSize surfaceSize = mSize;
|
||||
if (surfaceSize.IsEmpty()) {
|
||||
NSLog(@"NextSurface returning nullptr because of invalid surfaceSize (%d, %d).",
|
||||
surfaceSize.width, surfaceSize.height);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -256,22 +300,26 @@ CFTypeRefPtr<IOSurfaceRef> NativeLayerCA::NextSurface(const MutexAutoLock& aLock
|
|||
"ERROR: Do not call NextSurface twice in sequence. Call NotifySurfaceReady before the "
|
||||
"next call to NextSurface.");
|
||||
|
||||
// Find the last surface in unusedSurfaces. If such
|
||||
// Find the last surface in unusedSurfaces which has the right size. If such
|
||||
// a surface exists, it is the surface we will recycle.
|
||||
std::vector<SurfaceWithInvalidRegion> unusedSurfaces = RemoveExcessUnusedSurfaces(aLock);
|
||||
auto surfIter = std::find_if(
|
||||
unusedSurfaces.rbegin(), unusedSurfaces.rend(),
|
||||
[surfaceSize](const SurfaceWithInvalidRegion& s) { return s.mSize == surfaceSize; });
|
||||
|
||||
Maybe<SurfaceWithInvalidRegion> surf;
|
||||
if (!unusedSurfaces.empty()) {
|
||||
if (surfIter != unusedSurfaces.rend()) {
|
||||
// We found the surface we want to recycle.
|
||||
surf = Some(unusedSurfaces.back());
|
||||
surf = Some(*surfIter);
|
||||
|
||||
// Remove surf from unusedSurfaces.
|
||||
unusedSurfaces.pop_back();
|
||||
// The reverse iterator makes this a bit cumbersome.
|
||||
unusedSurfaces.erase(std::next(surfIter).base());
|
||||
} else {
|
||||
CFTypeRefPtr<IOSurfaceRef> newSurf = CFTypeRefPtr<IOSurfaceRef>::WrapUnderCreateRule(
|
||||
IOSurfaceCreate((__bridge CFDictionaryRef) @{
|
||||
(__bridge NSString*)kIOSurfaceWidth : @(mSize.width),
|
||||
(__bridge NSString*)kIOSurfaceHeight : @(mSize.height),
|
||||
(__bridge NSString*)kIOSurfaceWidth : @(surfaceSize.width),
|
||||
(__bridge NSString*)kIOSurfaceHeight : @(surfaceSize.height),
|
||||
(__bridge NSString*)kIOSurfacePixelFormat : @(kCVPixelFormatType_32BGRA),
|
||||
(__bridge NSString*)kIOSurfaceBytesPerElement : @(4),
|
||||
}));
|
||||
|
@ -279,11 +327,18 @@ CFTypeRefPtr<IOSurfaceRef> NativeLayerCA::NextSurface(const MutexAutoLock& aLock
|
|||
NSLog(@"NextSurface returning nullptr because IOSurfaceCreate failed to create the surface.");
|
||||
return nullptr;
|
||||
}
|
||||
surf = Some(SurfaceWithInvalidRegion{newSurf, IntRect({}, mSize)});
|
||||
if (mSurfaceRegistry) {
|
||||
mSurfaceRegistry->RegisterSurface(newSurf);
|
||||
}
|
||||
surf =
|
||||
Some(SurfaceWithInvalidRegion{newSurf, IntRect(IntPoint(0, 0), surfaceSize), surfaceSize});
|
||||
}
|
||||
|
||||
// Delete all other unused surfaces.
|
||||
for (auto unusedSurf : unusedSurfaces) {
|
||||
if (mSurfaceRegistry) {
|
||||
mSurfaceRegistry->UnregisterSurface(unusedSurf.mSurface);
|
||||
}
|
||||
mFramebuffers.erase(unusedSurf.mSurface);
|
||||
}
|
||||
unusedSurfaces.clear();
|
||||
|
@ -294,17 +349,13 @@ CFTypeRefPtr<IOSurfaceRef> NativeLayerCA::NextSurface(const MutexAutoLock& aLock
|
|||
return mInProgressSurface->mSurface;
|
||||
}
|
||||
|
||||
RefPtr<gfx::DrawTarget> NativeLayerCA::NextSurfaceAsDrawTarget(const gfx::IntRegion& aUpdateRegion,
|
||||
gfx::BackendType aBackendType) {
|
||||
RefPtr<gfx::DrawTarget> NativeLayerCA::NextSurfaceAsDrawTarget(gfx::BackendType aBackendType) {
|
||||
MutexAutoLock lock(mMutex);
|
||||
CFTypeRefPtr<IOSurfaceRef> surface = NextSurface(lock);
|
||||
if (!surface) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MOZ_RELEASE_ASSERT(IntRect({}, mSize).Contains(aUpdateRegion.GetBounds()));
|
||||
InvalidateRegionThroughoutSwapchain(lock, aUpdateRegion);
|
||||
|
||||
mInProgressLockedIOSurface = new MacIOSurface(std::move(surface));
|
||||
mInProgressLockedIOSurface->Lock(false);
|
||||
return mInProgressLockedIOSurface->GetAsDrawTargetLocked(aBackendType);
|
||||
|
@ -327,16 +378,13 @@ gl::GLContext* NativeLayerCA::GetGLContext() {
|
|||
return mGLContext;
|
||||
}
|
||||
|
||||
Maybe<GLuint> NativeLayerCA::NextSurfaceAsFramebuffer(const gfx::IntRegion& aUpdateRegion,
|
||||
bool aNeedsDepth) {
|
||||
Maybe<GLuint> NativeLayerCA::NextSurfaceAsFramebuffer(bool aNeedsDepth) {
|
||||
MutexAutoLock lock(mMutex);
|
||||
CFTypeRefPtr<IOSurfaceRef> surface = NextSurface(lock);
|
||||
if (!surface) {
|
||||
return Nothing();
|
||||
}
|
||||
|
||||
MOZ_RELEASE_ASSERT(IntRect({}, mSize).Contains(aUpdateRegion.GetBounds()));
|
||||
InvalidateRegionThroughoutSwapchain(lock, aUpdateRegion);
|
||||
return Some(GetOrCreateFramebufferForSurface(lock, std::move(surface), aNeedsDepth));
|
||||
}
|
||||
|
||||
|
@ -399,12 +447,6 @@ void NativeLayerCA::ApplyChanges() {
|
|||
mContentCALayer = [[CALayer layer] retain];
|
||||
mContentCALayer.anchorPoint = NSZeroPoint;
|
||||
mContentCALayer.contentsGravity = kCAGravityTopLeft;
|
||||
mContentCALayer.opaque = mIsOpaque;
|
||||
if ([mContentCALayer respondsToSelector:@selector(setContentsOpaque:)]) {
|
||||
// The opaque property seems to not be enough when using IOSurface contents.
|
||||
// Additionally, call the private method setContentsOpaque.
|
||||
[mContentCALayer setContentsOpaque:mIsOpaque];
|
||||
}
|
||||
[mWrappingCALayer addSublayer:mContentCALayer];
|
||||
}
|
||||
|
||||
|
@ -422,13 +464,7 @@ void NativeLayerCA::ApplyChanges() {
|
|||
auto globalLayerOrigin = mPosition;
|
||||
auto clipToLayerOffset = globalLayerOrigin - globalClipOrigin;
|
||||
|
||||
if (mMutatedBackingScale) {
|
||||
mContentCALayer.bounds =
|
||||
CGRectMake(0, 0, mSize.width / mBackingScale, mSize.height / mBackingScale);
|
||||
mContentCALayer.contentsScale = mBackingScale;
|
||||
}
|
||||
|
||||
if (mMutatedBackingScale || mMutatedClipRect) {
|
||||
if (mMutatedClipRect) {
|
||||
mWrappingCALayer.position =
|
||||
CGPointMake(globalClipOrigin.x / mBackingScale, globalClipOrigin.y / mBackingScale);
|
||||
if (mClipRect) {
|
||||
|
@ -440,12 +476,15 @@ void NativeLayerCA::ApplyChanges() {
|
|||
}
|
||||
}
|
||||
|
||||
if (mMutatedBackingScale || mMutatedPosition || mMutatedClipRect) {
|
||||
if (mMutatedPosition || mMutatedClipRect) {
|
||||
mContentCALayer.position =
|
||||
CGPointMake(clipToLayerOffset.x / mBackingScale, clipToLayerOffset.y / mBackingScale);
|
||||
}
|
||||
|
||||
if (mMutatedBackingScale || mMutatedSurfaceIsFlipped) {
|
||||
if (mMutatedSize) {
|
||||
mContentCALayer.bounds =
|
||||
CGRectMake(0, 0, mSize.width / mBackingScale, mSize.height / mBackingScale);
|
||||
mContentCALayer.contentsScale = mBackingScale;
|
||||
if (mSurfaceIsFlipped) {
|
||||
CGFloat height = mSize.height / mBackingScale;
|
||||
mContentCALayer.affineTransform = CGAffineTransformMake(1.0, 0.0, 0.0, -1.0, 0.0, height);
|
||||
|
@ -454,9 +493,18 @@ void NativeLayerCA::ApplyChanges() {
|
|||
}
|
||||
}
|
||||
|
||||
if (mMutatedIsOpaque) {
|
||||
mContentCALayer.opaque = mIsOpaque;
|
||||
if ([mContentCALayer respondsToSelector:@selector(setContentsOpaque:)]) {
|
||||
// The opaque property seems to not be enough when using IOSurface contents.
|
||||
// Additionally, call the private method setContentsOpaque.
|
||||
[mContentCALayer setContentsOpaque:mIsOpaque];
|
||||
}
|
||||
}
|
||||
|
||||
mMutatedPosition = false;
|
||||
mMutatedBackingScale = false;
|
||||
mMutatedSurfaceIsFlipped = false;
|
||||
mMutatedSize = false;
|
||||
mMutatedIsOpaque = false;
|
||||
mMutatedClipRect = false;
|
||||
|
||||
if (mReadySurface) {
|
||||
|
|
|
@ -1034,8 +1034,9 @@ Maybe<gfx::IntRect> BasicCompositor::BeginRenderingToNativeLayer(
|
|||
RefPtr<CompositingRenderTarget> target;
|
||||
aNativeLayer->SetSurfaceIsFlipped(false);
|
||||
IntRegion invalidRelativeToLayer = mInvalidRegion.MovedBy(-rect.TopLeft());
|
||||
RefPtr<DrawTarget> dt = aNativeLayer->NextSurfaceAsDrawTarget(
|
||||
invalidRelativeToLayer, BackendType::SKIA);
|
||||
aNativeLayer->InvalidateRegionThroughoutSwapchain(invalidRelativeToLayer);
|
||||
RefPtr<DrawTarget> dt =
|
||||
aNativeLayer->NextSurfaceAsDrawTarget(BackendType::SKIA);
|
||||
if (!dt) {
|
||||
return Nothing();
|
||||
}
|
||||
|
|
|
@ -834,6 +834,10 @@ void LayerManagerComposite::UpdateDebugOverlayNativeLayers() {
|
|||
bool drawFps = StaticPrefs::layers_acceleration_draw_fps();
|
||||
|
||||
if (drawFps) {
|
||||
if (!mGPUStatsLayer) {
|
||||
mGPUStatsLayer = mNativeLayerRoot->CreateLayer();
|
||||
}
|
||||
|
||||
GPUStats stats;
|
||||
stats.mScreenPixels = mRenderBounds.Area();
|
||||
mCompositor->GetFrameStats(&stats);
|
||||
|
@ -842,13 +846,9 @@ void LayerManagerComposite::UpdateDebugOverlayNativeLayers() {
|
|||
IntSize size = mTextRenderer->ComputeSurfaceSize(
|
||||
text, 600, TextRenderer::FontType::FixedWidth);
|
||||
|
||||
if (!mGPUStatsLayer || mGPUStatsLayer->GetSize() != size) {
|
||||
mGPUStatsLayer = mNativeLayerRoot->CreateLayer(size, false);
|
||||
}
|
||||
|
||||
mGPUStatsLayer->SetPosition(IntPoint(2, 5));
|
||||
RefPtr<DrawTarget> dt = mGPUStatsLayer->NextSurfaceAsDrawTarget(
|
||||
IntRect({}, size), BackendType::SKIA);
|
||||
mGPUStatsLayer->SetRect(IntRect(IntPoint(2, 5), size));
|
||||
RefPtr<DrawTarget> dt =
|
||||
mGPUStatsLayer->NextSurfaceAsDrawTarget(BackendType::SKIA);
|
||||
mTextRenderer->RenderTextToDrawTarget(dt, text, 600,
|
||||
TextRenderer::FontType::FixedWidth);
|
||||
mGPUStatsLayer->NotifySurfaceReady();
|
||||
|
@ -862,16 +862,17 @@ void LayerManagerComposite::UpdateDebugOverlayNativeLayers() {
|
|||
// If we have an unused APZ transform on this composite, draw a 20x20 red
|
||||
// box in the top-right corner.
|
||||
if (!mUnusedTransformWarningLayer) {
|
||||
mUnusedTransformWarningLayer =
|
||||
mNativeLayerRoot->CreateLayer(IntSize(20, 20), true);
|
||||
mUnusedTransformWarningLayer = mNativeLayerRoot->CreateLayer();
|
||||
mUnusedTransformWarningLayer->SetRect(IntRect(0, 0, 20, 20));
|
||||
mUnusedTransformWarningLayer->SetIsOpaque(true);
|
||||
RefPtr<DrawTarget> dt =
|
||||
mUnusedTransformWarningLayer->NextSurfaceAsDrawTarget(
|
||||
IntRect(0, 0, 20, 20), BackendType::SKIA);
|
||||
BackendType::SKIA);
|
||||
dt->FillRect(Rect(0, 0, 20, 20), ColorPattern(Color(1, 0, 0, 1)));
|
||||
mUnusedTransformWarningLayer->NotifySurfaceReady();
|
||||
}
|
||||
mUnusedTransformWarningLayer->SetPosition(
|
||||
IntPoint(mRenderBounds.XMost() - 20, mRenderBounds.Y()));
|
||||
mUnusedTransformWarningLayer->SetRect(
|
||||
IntRect(mRenderBounds.XMost() - 20, mRenderBounds.Y(), 20, 20));
|
||||
mNativeLayerRoot->AppendLayer(mUnusedTransformWarningLayer);
|
||||
|
||||
mUnusedApzTransformWarning = false;
|
||||
|
@ -883,16 +884,17 @@ void LayerManagerComposite::UpdateDebugOverlayNativeLayers() {
|
|||
// in the top-right corner, to the left of the unused-apz-transform
|
||||
// warning box.
|
||||
if (!mDisabledApzWarningLayer) {
|
||||
mDisabledApzWarningLayer =
|
||||
mNativeLayerRoot->CreateLayer(IntSize(20, 20), true);
|
||||
mDisabledApzWarningLayer = mNativeLayerRoot->CreateLayer();
|
||||
mDisabledApzWarningLayer->SetRect(IntRect(0, 0, 20, 20));
|
||||
mDisabledApzWarningLayer->SetIsOpaque(true);
|
||||
RefPtr<DrawTarget> dt =
|
||||
mDisabledApzWarningLayer->NextSurfaceAsDrawTarget(
|
||||
IntRect(0, 0, 20, 20), BackendType::SKIA);
|
||||
BackendType::SKIA);
|
||||
dt->FillRect(Rect(0, 0, 20, 20), ColorPattern(Color(1, 1, 0, 1)));
|
||||
mDisabledApzWarningLayer->NotifySurfaceReady();
|
||||
}
|
||||
mDisabledApzWarningLayer->SetPosition(
|
||||
IntPoint(mRenderBounds.XMost() - 40, mRenderBounds.Y()));
|
||||
mDisabledApzWarningLayer->SetRect(
|
||||
IntRect(mRenderBounds.XMost() - 40, mRenderBounds.Y(), 20, 20));
|
||||
mNativeLayerRoot->AppendLayer(mDisabledApzWarningLayer);
|
||||
|
||||
mDisabledApzWarning = false;
|
||||
|
@ -1006,22 +1008,20 @@ void LayerManagerComposite::PlaceNativeLayer(
|
|||
std::deque<RefPtr<NativeLayer>>* aLayersToRecycle,
|
||||
IntRegion* aWindowInvalidRegion) {
|
||||
RefPtr<NativeLayer> layer;
|
||||
if (aLayersToRecycle->empty() ||
|
||||
aLayersToRecycle->front()->GetSize() != aRect.Size() ||
|
||||
aLayersToRecycle->front()->IsOpaque() != aOpaque) {
|
||||
layer = mNativeLayerRoot->CreateLayer(aRect.Size(), aOpaque);
|
||||
if (aLayersToRecycle->empty()) {
|
||||
layer = mNativeLayerRoot->CreateLayer();
|
||||
mNativeLayerRoot->AppendLayer(layer);
|
||||
aWindowInvalidRegion->OrWith(aRect);
|
||||
} else {
|
||||
layer = aLayersToRecycle->front();
|
||||
aLayersToRecycle->pop_front();
|
||||
IntRect oldRect = layer->GetRect();
|
||||
if (!aRect.IsEqualInterior(oldRect)) {
|
||||
aWindowInvalidRegion->OrWith(oldRect);
|
||||
aWindowInvalidRegion->OrWith(aRect);
|
||||
}
|
||||
}
|
||||
layer->SetPosition(aRect.TopLeft());
|
||||
IntRect oldRect = layer->GetRect();
|
||||
if (!aRect.IsEqualInterior(oldRect)) {
|
||||
aWindowInvalidRegion->OrWith(oldRect);
|
||||
aWindowInvalidRegion->OrWith(aRect);
|
||||
}
|
||||
layer->SetRect(aRect);
|
||||
layer->SetIsOpaque(aOpaque);
|
||||
mNativeLayers.push_back(layer);
|
||||
}
|
||||
|
||||
|
|
|
@ -769,8 +769,8 @@ CompositorOGL::RenderTargetForNativeLayer(NativeLayer* aNativeLayer,
|
|||
IntRect layerRect = aNativeLayer->GetRect();
|
||||
IntRegion invalidRelativeToLayer =
|
||||
aInvalidRegion.MovedBy(-layerRect.TopLeft());
|
||||
Maybe<GLuint> fbo =
|
||||
aNativeLayer->NextSurfaceAsFramebuffer(invalidRelativeToLayer, false);
|
||||
aNativeLayer->InvalidateRegionThroughoutSwapchain(invalidRelativeToLayer);
|
||||
Maybe<GLuint> fbo = aNativeLayer->NextSurfaceAsFramebuffer(false);
|
||||
if (!fbo) {
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -36,6 +36,13 @@ RenderCompositorOGL::RenderCompositorOGL(
|
|||
mPreviousFrameDoneSync(nullptr),
|
||||
mThisFrameDoneSync(nullptr) {
|
||||
MOZ_ASSERT(mGL);
|
||||
|
||||
if (mNativeLayerRoot && !ShouldUseNativeCompositor()) {
|
||||
mNativeLayerForEntireWindow = mNativeLayerRoot->CreateLayer();
|
||||
mNativeLayerForEntireWindow->SetSurfaceIsFlipped(true);
|
||||
mNativeLayerForEntireWindow->SetGLContext(mGL);
|
||||
mNativeLayerRoot->AppendLayer(mNativeLayerForEntireWindow);
|
||||
}
|
||||
}
|
||||
|
||||
RenderCompositorOGL::~RenderCompositorOGL() {
|
||||
|
@ -68,25 +75,11 @@ bool RenderCompositorOGL::BeginFrame() {
|
|||
return false;
|
||||
}
|
||||
|
||||
gfx::IntSize bufferSize = GetBufferSize().ToUnknownSize();
|
||||
if (mNativeLayerRoot && !ShouldUseNativeCompositor()) {
|
||||
if (mNativeLayerForEntireWindow &&
|
||||
mNativeLayerForEntireWindow->GetSize() != bufferSize) {
|
||||
mNativeLayerRoot->RemoveLayer(mNativeLayerForEntireWindow);
|
||||
mNativeLayerForEntireWindow = nullptr;
|
||||
}
|
||||
if (!mNativeLayerForEntireWindow) {
|
||||
mNativeLayerForEntireWindow =
|
||||
mNativeLayerRoot->CreateLayer(bufferSize, false);
|
||||
mNativeLayerForEntireWindow->SetSurfaceIsFlipped(true);
|
||||
mNativeLayerForEntireWindow->SetGLContext(mGL);
|
||||
mNativeLayerRoot->AppendLayer(mNativeLayerForEntireWindow);
|
||||
}
|
||||
}
|
||||
if (mNativeLayerForEntireWindow) {
|
||||
gfx::IntRect bounds({}, bufferSize);
|
||||
gfx::IntRect bounds({}, GetBufferSize().ToUnknownSize());
|
||||
mNativeLayerForEntireWindow->SetRect(bounds);
|
||||
Maybe<GLuint> fbo =
|
||||
mNativeLayerForEntireWindow->NextSurfaceAsFramebuffer(bounds, true);
|
||||
mNativeLayerForEntireWindow->NextSurfaceAsFramebuffer(true);
|
||||
if (!fbo) {
|
||||
return false;
|
||||
}
|
||||
|
@ -189,7 +182,7 @@ void RenderCompositorOGL::Bind(wr::NativeSurfaceId aId,
|
|||
"We currently do not support partial updates (max_update_rects is set to "
|
||||
"0), so we expect the dirty rect to always cover the entire layer.");
|
||||
|
||||
Maybe<GLuint> fbo = layer->NextSurfaceAsFramebuffer(dirtyRect, true);
|
||||
Maybe<GLuint> fbo = layer->NextSurfaceAsFramebuffer(true);
|
||||
MOZ_RELEASE_ASSERT(fbo); // TODO: make fallible
|
||||
mCurrentlyBoundNativeLayer = layer;
|
||||
|
||||
|
@ -210,9 +203,10 @@ void RenderCompositorOGL::Unbind() {
|
|||
void RenderCompositorOGL::CreateSurface(wr::NativeSurfaceId aId,
|
||||
wr::DeviceIntSize aSize,
|
||||
bool aIsOpaque) {
|
||||
RefPtr<layers::NativeLayer> layer = mNativeLayerRoot->CreateLayer(
|
||||
IntSize(aSize.width, aSize.height), aIsOpaque);
|
||||
RefPtr<layers::NativeLayer> layer = mNativeLayerRoot->CreateLayer();
|
||||
layer->SetRect(gfx::IntRect(0, 0, aSize.width, aSize.height));
|
||||
layer->SetGLContext(mGL);
|
||||
layer->SetIsOpaque(aIsOpaque);
|
||||
mNativeLayers.insert({wr::AsUint64(aId), layer});
|
||||
}
|
||||
|
||||
|
@ -238,12 +232,12 @@ void RenderCompositorOGL::AddSurface(wr::NativeSurfaceId aId,
|
|||
MOZ_RELEASE_ASSERT(layerCursor != mNativeLayers.end());
|
||||
RefPtr<layers::NativeLayer> layer = layerCursor->second;
|
||||
|
||||
gfx::IntSize layerSize = layer->GetSize();
|
||||
gfx::IntSize layerSize = layer->GetRect().Size();
|
||||
gfx::IntRect layerRect(aPosition.x, aPosition.y, layerSize.width,
|
||||
layerSize.height);
|
||||
gfx::IntRect clipRect(aClipRect.origin.x, aClipRect.origin.y,
|
||||
aClipRect.size.width, aClipRect.size.height);
|
||||
layer->SetPosition(layerRect.TopLeft());
|
||||
layer->SetRect(layerRect);
|
||||
layer->SetClipRect(Some(clipRect));
|
||||
mAddedLayers.AppendElement(layer);
|
||||
|
||||
|
|
|
@ -705,9 +705,6 @@ class nsChildView final : public nsBaseWidget {
|
|||
// Always null if StaticPrefs::gfx_core_animation_enabled_AtStartup() is false.
|
||||
RefPtr<mozilla::layers::NativeLayerCA> mContentLayer;
|
||||
|
||||
// In BasicLayers mode, this is the invalid region of mContentLayer.
|
||||
LayoutDeviceIntRegion mContentLayerInvalidRegion;
|
||||
|
||||
mozilla::UniquePtr<mozilla::VibrancyManager> mVibrancyManager;
|
||||
RefPtr<mozilla::SwipeTracker> mSwipeTracker;
|
||||
mozilla::UniquePtr<mozilla::SwipeEventQueue> mSwipeEventQueue;
|
||||
|
|
|
@ -1294,7 +1294,7 @@ void nsChildView::Invalidate(const LayoutDeviceIntRect& aRect) {
|
|||
|
||||
if (StaticPrefs::gfx_core_animation_enabled_AtStartup()) {
|
||||
EnsureContentLayerForMainThreadPainting();
|
||||
mContentLayerInvalidRegion.OrWith(aRect.Intersect(GetBounds()));
|
||||
mContentLayer->InvalidateRegionThroughoutSwapchain(aRect.ToUnknownRect());
|
||||
[mView markLayerForDisplay];
|
||||
} else {
|
||||
[[mView pixelHostingView] setNeedsDisplayInRect:DevPixelsToCocoaPoints(aRect)];
|
||||
|
@ -1488,28 +1488,21 @@ bool nsChildView::PaintWindowInContext(CGContextRef aContext, const LayoutDevice
|
|||
}
|
||||
|
||||
void nsChildView::EnsureContentLayerForMainThreadPainting() {
|
||||
// Ensure we have an mContentLayer of the correct size.
|
||||
// The content layer gets created on demand for BasicLayers windows. We do
|
||||
// not create it during widget creation because, for non-BasicLayers windows,
|
||||
// the compositing layer manager will create any layers it needs.
|
||||
gfx::IntSize size = GetBounds().Size().ToUnknownSize();
|
||||
if (mContentLayer && mContentLayer->GetSize() != size) {
|
||||
mNativeLayerRoot->RemoveLayer(mContentLayer);
|
||||
mContentLayer = nullptr;
|
||||
}
|
||||
if (!mContentLayer) {
|
||||
RefPtr<NativeLayer> contentLayer = mNativeLayerRoot->CreateLayer(size, false);
|
||||
// The content layer gets created on demand for BasicLayers windows. We do
|
||||
// not create it during widget creation because, for non-BasicLayers windows,
|
||||
// the compositing layer manager will create any layers it needs.
|
||||
RefPtr<NativeLayer> contentLayer = mNativeLayerRoot->CreateLayer();
|
||||
mNativeLayerRoot->AppendLayer(contentLayer);
|
||||
mContentLayer = contentLayer->AsNativeLayerCA();
|
||||
mContentLayerInvalidRegion = GetBounds();
|
||||
}
|
||||
}
|
||||
|
||||
void nsChildView::PaintWindowInContentLayer() {
|
||||
EnsureContentLayerForMainThreadPainting();
|
||||
mContentLayer->SetRect(GetBounds().ToUnknownRect());
|
||||
mContentLayer->SetSurfaceIsFlipped(false);
|
||||
RefPtr<DrawTarget> dt = mContentLayer->NextSurfaceAsDrawTarget(
|
||||
mContentLayerInvalidRegion.ToUnknownRegion(), gfx::BackendType::SKIA);
|
||||
RefPtr<DrawTarget> dt = mContentLayer->NextSurfaceAsDrawTarget(gfx::BackendType::SKIA);
|
||||
if (!dt) {
|
||||
return;
|
||||
}
|
||||
|
@ -1518,7 +1511,6 @@ void nsChildView::PaintWindowInContentLayer() {
|
|||
dt, LayoutDeviceIntRegion::FromUnknownRegion(mContentLayer->CurrentSurfaceInvalidRegion()),
|
||||
dt->GetSize());
|
||||
mContentLayer->NotifySurfaceReady();
|
||||
mContentLayerInvalidRegion.SetEmpty();
|
||||
}
|
||||
|
||||
void nsChildView::HandleMainThreadCATransaction() {
|
||||
|
|
Загрузка…
Ссылка в новой задаче