2018-01-15 16:22:15 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
|
|
/* 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/. */
|
|
|
|
|
|
|
|
#ifndef MOZILLA_GFX_RENDERCOMPOSITOR_OGL_H
|
|
|
|
#define MOZILLA_GFX_RENDERCOMPOSITOR_OGL_H
|
|
|
|
|
|
|
|
#include "mozilla/webrender/RenderCompositor.h"
|
2019-11-28 02:07:51 +03:00
|
|
|
#include "mozilla/TimeStamp.h"
|
2018-01-15 16:22:15 +03:00
|
|
|
|
|
|
|
namespace mozilla {
|
2018-01-19 05:01:04 +03:00
|
|
|
|
2019-10-29 23:50:33 +03:00
|
|
|
namespace layers {
|
2019-12-29 15:41:58 +03:00
|
|
|
class NativeLayerRootSnapshotter;
|
2019-10-29 23:50:33 +03:00
|
|
|
class NativeLayerRoot;
|
|
|
|
class NativeLayer;
|
Bug 1592044 - Reduce the frequency of IOSurface and framebuffer creation and destruction with the help of a surface pool. r=jgilbert
There are multiple SurfacePools: Main thread painting and the non-WebRender compositors create a new pool per window, and WebRender creates one shared pool across all windows. The non-WebRender users set the pool size limit to zero, i.e. no recycling across paints. This preserves the pre-existing behavior.
WebRender's pool size is configurable with the gfx.webrender.compositor.surface-pool-size pref.
Every window holds on to a SurfacePoolHandle. A SurfacePoolHandle has an owning reference to the pool, via a surface pool wrapper. Once all handles are gone, the surface pool goes away, too.
The SurfacePool holds on to IOSurfaces and MozFramebuffers. Both are created on demand, independently, but are associated with each other.
A given NativeLayer uses only one surface pool handle during its lifetime. The native layer no longer influences which GLContext its framebuffers are created for; the GL context is now managed by the surface pool handle.
As a result, a NativeLayer can no longer change which GLContext its framebuffers are created by.
So in the future, if we ever need to migrate a window frome one GLContext to another, we will need to recreate the NativeLayers inside it. I think that's ok.
Differential Revision: https://phabricator.services.mozilla.com/D54859
--HG--
extra : moz-landing-system : lando
2019-12-19 00:01:51 +03:00
|
|
|
class SurfacePoolHandle;
|
2019-10-29 23:50:33 +03:00
|
|
|
} // namespace layers
|
|
|
|
|
2018-01-15 16:22:15 +03:00
|
|
|
namespace wr {
|
|
|
|
|
|
|
|
class RenderCompositorOGL : public RenderCompositor {
|
|
|
|
public:
|
|
|
|
static UniquePtr<RenderCompositor> Create(
|
|
|
|
RefPtr<widget::CompositorWidget>&& aWidget);
|
|
|
|
|
|
|
|
RenderCompositorOGL(RefPtr<gl::GLContext>&& aGL,
|
2018-01-19 05:01:04 +03:00
|
|
|
RefPtr<widget::CompositorWidget>&& aWidget);
|
2018-01-15 16:22:15 +03:00
|
|
|
virtual ~RenderCompositorOGL();
|
|
|
|
|
2019-10-29 23:50:33 +03:00
|
|
|
bool BeginFrame() override;
|
2019-11-04 19:15:20 +03:00
|
|
|
RenderedFrameId EndFrame(const FfiVec<DeviceIntRect>& aDirtyRects) final;
|
2019-07-17 23:46:39 +03:00
|
|
|
bool WaitForGPU() override;
|
2018-01-15 16:22:15 +03:00
|
|
|
void Pause() override;
|
|
|
|
bool Resume() override;
|
|
|
|
|
|
|
|
gl::GLContext* gl() const override { return mGL; }
|
|
|
|
|
2018-01-19 05:01:04 +03:00
|
|
|
bool UseANGLE() const override { return false; }
|
2018-01-15 16:22:15 +03:00
|
|
|
|
2018-02-01 15:39:31 +03:00
|
|
|
LayoutDeviceIntSize GetBufferSize() override;
|
2018-01-15 16:22:15 +03:00
|
|
|
|
2019-10-29 23:54:09 +03:00
|
|
|
bool ShouldUseNativeCompositor() override;
|
2019-11-19 06:33:43 +03:00
|
|
|
uint32_t GetMaxUpdateRects() override;
|
2019-10-29 23:54:09 +03:00
|
|
|
|
2019-12-29 15:41:58 +03:00
|
|
|
// Does the readback for the ShouldUseNativeCompositor() case.
|
|
|
|
bool MaybeReadback(const gfx::IntSize& aReadbackSize,
|
|
|
|
const wr::ImageFormat& aReadbackFormat,
|
|
|
|
const Range<uint8_t>& aReadbackBuffer) override;
|
|
|
|
|
2019-10-29 23:54:09 +03:00
|
|
|
// Interface for wr::Compositor
|
|
|
|
void CompositorBeginFrame() override;
|
|
|
|
void CompositorEndFrame() override;
|
2019-12-18 00:44:03 +03:00
|
|
|
void Bind(wr::NativeTileId aId, wr::DeviceIntPoint* aOffset, uint32_t* aFboId,
|
|
|
|
wr::DeviceIntRect aDirtyRect) override;
|
2019-10-29 23:54:09 +03:00
|
|
|
void Unbind() override;
|
2020-01-06 23:11:21 +03:00
|
|
|
void CreateSurface(wr::NativeSurfaceId aId, wr::DeviceIntSize aTileSize,
|
|
|
|
bool aIsOpaque) override;
|
2019-10-29 23:54:09 +03:00
|
|
|
void DestroySurface(NativeSurfaceId aId) override;
|
2020-01-06 23:11:21 +03:00
|
|
|
void CreateTile(wr::NativeSurfaceId aId, int32_t aX, int32_t aY) override;
|
2019-12-18 00:44:03 +03:00
|
|
|
void DestroyTile(wr::NativeSurfaceId aId, int32_t aX, int32_t aY) override;
|
2019-10-29 23:54:09 +03:00
|
|
|
void AddSurface(wr::NativeSurfaceId aId, wr::DeviceIntPoint aPosition,
|
|
|
|
wr::DeviceIntRect aClipRect) override;
|
|
|
|
|
2019-12-18 00:44:03 +03:00
|
|
|
struct TileKey {
|
|
|
|
TileKey(int32_t aX, int32_t aY) : mX(aX), mY(aY) {}
|
|
|
|
|
|
|
|
int32_t mX;
|
|
|
|
int32_t mY;
|
|
|
|
};
|
|
|
|
|
2018-01-15 16:22:15 +03:00
|
|
|
protected:
|
2019-07-17 23:46:39 +03:00
|
|
|
void InsertFrameDoneSync();
|
|
|
|
|
2018-01-15 16:22:15 +03:00
|
|
|
RefPtr<gl::GLContext> mGL;
|
2019-07-17 23:46:39 +03:00
|
|
|
|
2019-10-29 23:50:33 +03:00
|
|
|
// Can be null.
|
|
|
|
RefPtr<layers::NativeLayerRoot> mNativeLayerRoot;
|
2019-12-29 15:41:58 +03:00
|
|
|
UniquePtr<layers::NativeLayerRootSnapshotter> mNativeLayerRootSnapshotter;
|
2019-10-29 23:50:33 +03:00
|
|
|
RefPtr<layers::NativeLayer> mNativeLayerForEntireWindow;
|
Bug 1592044 - Reduce the frequency of IOSurface and framebuffer creation and destruction with the help of a surface pool. r=jgilbert
There are multiple SurfacePools: Main thread painting and the non-WebRender compositors create a new pool per window, and WebRender creates one shared pool across all windows. The non-WebRender users set the pool size limit to zero, i.e. no recycling across paints. This preserves the pre-existing behavior.
WebRender's pool size is configurable with the gfx.webrender.compositor.surface-pool-size pref.
Every window holds on to a SurfacePoolHandle. A SurfacePoolHandle has an owning reference to the pool, via a surface pool wrapper. Once all handles are gone, the surface pool goes away, too.
The SurfacePool holds on to IOSurfaces and MozFramebuffers. Both are created on demand, independently, but are associated with each other.
A given NativeLayer uses only one surface pool handle during its lifetime. The native layer no longer influences which GLContext its framebuffers are created for; the GL context is now managed by the surface pool handle.
As a result, a NativeLayer can no longer change which GLContext its framebuffers are created by.
So in the future, if we ever need to migrate a window frome one GLContext to another, we will need to recreate the NativeLayers inside it. I think that's ok.
Differential Revision: https://phabricator.services.mozilla.com/D54859
--HG--
extra : moz-landing-system : lando
2019-12-19 00:01:51 +03:00
|
|
|
RefPtr<layers::SurfacePoolHandle> mSurfacePoolHandle;
|
2019-10-29 22:25:39 +03:00
|
|
|
|
2019-12-18 00:44:03 +03:00
|
|
|
struct TileKeyHashFn {
|
|
|
|
std::size_t operator()(const TileKey& aId) const {
|
|
|
|
return HashGeneric(aId.mX, aId.mY);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class Surface {
|
|
|
|
public:
|
2020-01-06 23:11:21 +03:00
|
|
|
explicit Surface(wr::DeviceIntSize aTileSize, bool aIsOpaque)
|
|
|
|
: mTileSize(aTileSize), mIsOpaque(aIsOpaque) {}
|
2019-12-18 00:44:03 +03:00
|
|
|
|
|
|
|
wr::DeviceIntSize mTileSize;
|
2020-01-06 23:11:21 +03:00
|
|
|
bool mIsOpaque;
|
2019-12-18 00:44:03 +03:00
|
|
|
std::unordered_map<TileKey, RefPtr<layers::NativeLayer>, TileKeyHashFn>
|
|
|
|
mNativeLayers;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct SurfaceIdHashFn {
|
|
|
|
std::size_t operator()(const wr::NativeSurfaceId& aId) const {
|
|
|
|
return HashGeneric(wr::AsUint64(aId));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-10-29 23:54:09 +03:00
|
|
|
// Used in native compositor mode:
|
|
|
|
RefPtr<layers::NativeLayer> mCurrentlyBoundNativeLayer;
|
|
|
|
nsTArray<RefPtr<layers::NativeLayer>> mAddedLayers;
|
2019-11-28 02:07:26 +03:00
|
|
|
uint64_t mTotalPixelCount = 0;
|
2019-10-29 23:54:09 +03:00
|
|
|
uint64_t mAddedPixelCount = 0;
|
|
|
|
uint64_t mAddedClippedPixelCount = 0;
|
|
|
|
uint64_t mDrawnPixelCount = 0;
|
|
|
|
gfx::IntRect mVisibleBounds;
|
2019-12-18 00:44:03 +03:00
|
|
|
std::unordered_map<wr::NativeSurfaceId, Surface, SurfaceIdHashFn> mSurfaces;
|
2019-11-28 02:07:51 +03:00
|
|
|
TimeStamp mBeginFrameTimeStamp;
|
2019-10-29 23:54:09 +03:00
|
|
|
|
2019-07-17 23:46:39 +03:00
|
|
|
// Used to apply back-pressure in WaitForGPU().
|
|
|
|
GLsync mPreviousFrameDoneSync;
|
|
|
|
GLsync mThisFrameDoneSync;
|
2018-01-15 16:22:15 +03:00
|
|
|
};
|
|
|
|
|
2019-12-18 00:44:03 +03:00
|
|
|
static inline bool operator==(const RenderCompositorOGL::TileKey& a0,
|
|
|
|
const RenderCompositorOGL::TileKey& a1) {
|
|
|
|
return a0.mX == a1.mX && a0.mY == a1.mY;
|
|
|
|
}
|
|
|
|
|
2018-01-15 16:22:15 +03:00
|
|
|
} // namespace wr
|
|
|
|
} // namespace mozilla
|
|
|
|
|
|
|
|
#endif
|