1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef MOZILLA_GFX_RENDERCOMPOSITOR_NATIVE_H
8 #define MOZILLA_GFX_RENDERCOMPOSITOR_NATIVE_H
10 #include <unordered_map>
13 #include "mozilla/HashFunctions.h"
14 #include "mozilla/layers/ScreenshotGrabber.h"
15 #include "mozilla/webrender/RenderCompositor.h"
16 #include "mozilla/TimeStamp.h"
21 class NativeLayerRootSnapshotter
;
22 class NativeLayerRoot
;
24 class SurfacePoolHandle
;
29 // RenderCompositorNative is a skeleton class for implementing compositors
30 // backed by NativeLayer surfaces and tiles. This is not meant to be directly
31 // instantiated and is instead derived for various use-cases such as OpenGL or
33 class RenderCompositorNative
: public RenderCompositor
{
35 virtual ~RenderCompositorNative();
37 bool BeginFrame() override
;
38 RenderedFrameId
EndFrame(const nsTArray
<DeviceIntRect
>& aDirtyRects
) final
;
39 void Pause() override
;
40 bool Resume() override
;
42 layers::WebRenderCompositor
CompositorType() const override
;
44 LayoutDeviceIntSize
GetBufferSize() override
;
46 bool ShouldUseNativeCompositor() override
;
47 uint32_t GetMaxUpdateRects() override
;
49 // Does the readback for the ShouldUseNativeCompositor() case.
50 bool MaybeReadback(const gfx::IntSize
& aReadbackSize
,
51 const wr::ImageFormat
& aReadbackFormat
,
52 const Range
<uint8_t>& aReadbackBuffer
,
53 bool* aNeedsYFlip
) override
;
54 bool MaybeRecordFrame(layers::CompositionRecorder
& aRecorder
) override
;
55 bool MaybeGrabScreenshot(const gfx::IntSize
& aWindowSize
) override
;
56 bool MaybeProcessScreenshotQueue() override
;
58 // Interface for wr::Compositor
59 void CompositorBeginFrame() override
;
60 void CompositorEndFrame() override
;
61 void CreateSurface(wr::NativeSurfaceId aId
, wr::DeviceIntPoint aVirtualOffset
,
62 wr::DeviceIntSize aTileSize
, bool aIsOpaque
) override
;
63 void CreateExternalSurface(wr::NativeSurfaceId aId
, bool aIsOpaque
) override
;
64 void DestroySurface(NativeSurfaceId aId
) override
;
65 void CreateTile(wr::NativeSurfaceId aId
, int32_t aX
, int32_t aY
) override
;
66 void DestroyTile(wr::NativeSurfaceId aId
, int32_t aX
, int32_t aY
) override
;
67 void AttachExternalImage(wr::NativeSurfaceId aId
,
68 wr::ExternalImageId aExternalImage
) override
;
69 void AddSurface(wr::NativeSurfaceId aId
,
70 const wr::CompositorSurfaceTransform
& aTransform
,
71 wr::DeviceIntRect aClipRect
,
72 wr::ImageRendering aImageRendering
) override
;
75 TileKey(int32_t aX
, int32_t aY
) : mX(aX
), mY(aY
) {}
82 explicit RenderCompositorNative(RefPtr
<widget::CompositorWidget
>&& aWidget
,
83 gl::GLContext
* aGL
= nullptr);
85 virtual bool InitDefaultFramebuffer(const gfx::IntRect
& aBounds
) = 0;
86 virtual void DoSwap() = 0;
87 virtual void DoFlush() {}
89 void BindNativeLayer(wr::NativeTileId aId
, const gfx::IntRect
& aDirtyRect
);
90 void UnbindNativeLayer();
93 RefPtr
<layers::NativeLayerRoot
> mNativeLayerRoot
;
94 UniquePtr
<layers::NativeLayerRootSnapshotter
> mNativeLayerRootSnapshotter
;
95 layers::ScreenshotGrabber mProfilerScreenshotGrabber
;
96 RefPtr
<layers::NativeLayer
> mNativeLayerForEntireWindow
;
97 RefPtr
<layers::SurfacePoolHandle
> mSurfacePoolHandle
;
99 struct TileKeyHashFn
{
100 std::size_t operator()(const TileKey
& aId
) const {
101 return HashGeneric(aId
.mX
, aId
.mY
);
106 explicit Surface(wr::DeviceIntSize aTileSize
, bool aIsOpaque
)
107 : mTileSize(aTileSize
), mIsOpaque(aIsOpaque
) {}
108 gfx::IntSize
TileSize() {
109 return gfx::IntSize(mTileSize
.width
, mTileSize
.height
);
112 // External images can change size depending on which image
113 // is attached, so mTileSize will be 0,0 when mIsExternal
115 wr::DeviceIntSize mTileSize
;
117 bool mIsExternal
= false;
118 std::unordered_map
<TileKey
, RefPtr
<layers::NativeLayer
>, TileKeyHashFn
>
122 struct SurfaceIdHashFn
{
123 std::size_t operator()(const wr::NativeSurfaceId
& aId
) const {
124 return HashGeneric(wr::AsUint64(aId
));
128 // Used in native compositor mode:
129 RefPtr
<layers::NativeLayer
> mCurrentlyBoundNativeLayer
;
130 nsTArray
<RefPtr
<layers::NativeLayer
>> mAddedLayers
;
131 uint64_t mTotalTilePixelCount
= 0;
132 uint64_t mAddedTilePixelCount
= 0;
133 uint64_t mAddedClippedPixelCount
= 0;
134 uint64_t mDrawnPixelCount
= 0;
135 gfx::IntRect mVisibleBounds
;
136 std::unordered_map
<wr::NativeSurfaceId
, Surface
, SurfaceIdHashFn
> mSurfaces
;
137 TimeStamp mBeginFrameTimeStamp
;
140 static inline bool operator==(const RenderCompositorNative::TileKey
& a0
,
141 const RenderCompositorNative::TileKey
& a1
) {
142 return a0
.mX
== a1
.mX
&& a0
.mY
== a1
.mY
;
145 // RenderCompositorNativeOGL is a NativeLayer compositor that exposes an
146 // OpenGL framebuffer for the respective NativeLayer bound to each tile.
147 class RenderCompositorNativeOGL
: public RenderCompositorNative
{
149 static UniquePtr
<RenderCompositor
> Create(
150 RefPtr
<widget::CompositorWidget
>&& aWidget
, nsACString
& aError
);
152 RenderCompositorNativeOGL(RefPtr
<widget::CompositorWidget
>&& aWidget
,
153 RefPtr
<gl::GLContext
>&& aGL
);
154 virtual ~RenderCompositorNativeOGL();
156 bool WaitForGPU() override
;
158 gl::GLContext
* gl() const override
{ return mGL
; }
160 void Bind(wr::NativeTileId aId
, wr::DeviceIntPoint
* aOffset
, uint32_t* aFboId
,
161 wr::DeviceIntRect aDirtyRect
,
162 wr::DeviceIntRect aValidRect
) override
;
163 void Unbind() override
;
166 void InsertFrameDoneSync();
168 bool InitDefaultFramebuffer(const gfx::IntRect
& aBounds
) override
;
169 void DoSwap() override
;
170 void DoFlush() override
;
172 RefPtr
<gl::GLContext
> mGL
;
174 // Used to apply back-pressure in WaitForGPU().
175 GLsync mPreviousFrameDoneSync
= nullptr;
176 GLsync mThisFrameDoneSync
= nullptr;
179 // RenderCompositorNativeSWGL is a NativeLayer compositor that only
180 // deals with mapping the underlying buffer for SWGL usage of a tile.
181 class RenderCompositorNativeSWGL
: public RenderCompositorNative
{
183 static UniquePtr
<RenderCompositor
> Create(
184 RefPtr
<widget::CompositorWidget
>&& aWidget
, nsACString
& aError
);
186 RenderCompositorNativeSWGL(RefPtr
<widget::CompositorWidget
>&& aWidget
,
188 virtual ~RenderCompositorNativeSWGL();
190 void* swgl() const override
{ return mContext
; }
192 bool MakeCurrent() override
;
194 void CancelFrame() override
;
196 layers::WebRenderBackend
BackendType() const override
{
197 return layers::WebRenderBackend::SOFTWARE
;
200 // Maps an underlying layer and sets aData to the top left pixel of
201 // aValidRect. The row stride is set to aStride, note this doesn't
202 // mean there are always aStride bytes available per row (the
203 // last row will fall short if aValidRect is not at X==0).
204 bool MapTile(wr::NativeTileId aId
, wr::DeviceIntRect aDirtyRect
,
205 wr::DeviceIntRect aValidRect
, void** aData
,
206 int32_t* aStride
) override
;
207 void UnmapTile() override
;
210 bool InitDefaultFramebuffer(const gfx::IntRect
& aBounds
) override
;
211 void DoSwap() override
;
213 bool MapNativeLayer(layers::NativeLayer
* aLayer
,
214 const gfx::IntRect
& aDirtyRect
,
215 const gfx::IntRect
& aValidRect
);
216 void UnmapNativeLayer();
218 void* mContext
= nullptr;
219 RefPtr
<gfx::DrawTarget
> mLayerTarget
;
220 uint8_t* mLayerData
= nullptr;
221 uint8_t* mLayerValidRectData
= nullptr;
222 int32_t mLayerStride
= 0;
226 } // namespace mozilla