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 void GetCompositorCapabilities(CompositorCapabilities
* aCaps
) override
;
49 bool SurfaceOriginIsTopLeft() override
{ return true; }
51 // Does the readback for the ShouldUseNativeCompositor() case.
52 bool MaybeReadback(const gfx::IntSize
& aReadbackSize
,
53 const wr::ImageFormat
& aReadbackFormat
,
54 const Range
<uint8_t>& aReadbackBuffer
,
55 bool* aNeedsYFlip
) override
;
56 bool MaybeRecordFrame(layers::CompositionRecorder
& aRecorder
) override
;
57 bool MaybeGrabScreenshot(const gfx::IntSize
& aWindowSize
) override
;
58 bool MaybeProcessScreenshotQueue() override
;
60 // Interface for wr::Compositor
61 void CompositorBeginFrame() override
;
62 void CompositorEndFrame() override
;
63 void CreateSurface(wr::NativeSurfaceId aId
, wr::DeviceIntPoint aVirtualOffset
,
64 wr::DeviceIntSize aTileSize
, bool aIsOpaque
) override
;
65 void CreateExternalSurface(wr::NativeSurfaceId aId
, bool aIsOpaque
) override
;
66 void CreateBackdropSurface(wr::NativeSurfaceId aId
,
67 wr::ColorF aColor
) override
;
68 void DestroySurface(NativeSurfaceId aId
) override
;
69 void CreateTile(wr::NativeSurfaceId aId
, int32_t aX
, int32_t aY
) override
;
70 void DestroyTile(wr::NativeSurfaceId aId
, int32_t aX
, int32_t aY
) override
;
71 void AttachExternalImage(wr::NativeSurfaceId aId
,
72 wr::ExternalImageId aExternalImage
) override
;
73 void AddSurface(wr::NativeSurfaceId aId
,
74 const wr::CompositorSurfaceTransform
& aTransform
,
75 wr::DeviceIntRect aClipRect
,
76 wr::ImageRendering aImageRendering
) override
;
79 TileKey(int32_t aX
, int32_t aY
) : mX(aX
), mY(aY
) {}
86 explicit RenderCompositorNative(
87 const RefPtr
<widget::CompositorWidget
>& aWidget
,
88 gl::GLContext
* aGL
= nullptr);
90 virtual bool InitDefaultFramebuffer(const gfx::IntRect
& aBounds
) = 0;
91 virtual void DoSwap() = 0;
92 virtual void DoFlush() {}
94 void BindNativeLayer(wr::NativeTileId aId
, const gfx::IntRect
& aDirtyRect
);
95 void UnbindNativeLayer();
98 RefPtr
<layers::NativeLayerRoot
> mNativeLayerRoot
;
99 UniquePtr
<layers::NativeLayerRootSnapshotter
> mNativeLayerRootSnapshotter
;
100 layers::ScreenshotGrabber mProfilerScreenshotGrabber
;
101 RefPtr
<layers::NativeLayer
> mNativeLayerForEntireWindow
;
102 RefPtr
<layers::SurfacePoolHandle
> mSurfacePoolHandle
;
104 struct TileKeyHashFn
{
105 std::size_t operator()(const TileKey
& aId
) const {
106 return HashGeneric(aId
.mX
, aId
.mY
);
111 explicit Surface(wr::DeviceIntSize aTileSize
, bool aIsOpaque
)
112 : mTileSize(aTileSize
), mIsOpaque(aIsOpaque
) {}
113 gfx::IntSize
TileSize() {
114 return gfx::IntSize(mTileSize
.width
, mTileSize
.height
);
117 // External images can change size depending on which image
118 // is attached, so mTileSize will be 0,0 when mIsExternal
120 wr::DeviceIntSize mTileSize
;
122 bool mIsExternal
= false;
123 std::unordered_map
<TileKey
, RefPtr
<layers::NativeLayer
>, TileKeyHashFn
>
127 struct SurfaceIdHashFn
{
128 std::size_t operator()(const wr::NativeSurfaceId
& aId
) const {
129 return HashGeneric(wr::AsUint64(aId
));
133 // Used in native compositor mode:
134 RefPtr
<layers::NativeLayer
> mCurrentlyBoundNativeLayer
;
135 nsTArray
<RefPtr
<layers::NativeLayer
>> mAddedLayers
;
136 uint64_t mTotalTilePixelCount
= 0;
137 uint64_t mAddedTilePixelCount
= 0;
138 uint64_t mAddedClippedPixelCount
= 0;
139 uint64_t mDrawnPixelCount
= 0;
140 gfx::IntRect mVisibleBounds
;
141 std::unordered_map
<wr::NativeSurfaceId
, Surface
, SurfaceIdHashFn
> mSurfaces
;
142 TimeStamp mBeginFrameTimeStamp
;
145 static inline bool operator==(const RenderCompositorNative::TileKey
& a0
,
146 const RenderCompositorNative::TileKey
& a1
) {
147 return a0
.mX
== a1
.mX
&& a0
.mY
== a1
.mY
;
150 // RenderCompositorNativeOGL is a NativeLayer compositor that exposes an
151 // OpenGL framebuffer for the respective NativeLayer bound to each tile.
152 class RenderCompositorNativeOGL
: public RenderCompositorNative
{
154 static UniquePtr
<RenderCompositor
> Create(
155 const RefPtr
<widget::CompositorWidget
>& aWidget
, nsACString
& aError
);
157 RenderCompositorNativeOGL(const RefPtr
<widget::CompositorWidget
>& aWidget
,
158 RefPtr
<gl::GLContext
>&& aGL
);
159 virtual ~RenderCompositorNativeOGL();
161 bool WaitForGPU() override
;
163 gl::GLContext
* gl() const override
{ return mGL
; }
165 void Bind(wr::NativeTileId aId
, wr::DeviceIntPoint
* aOffset
, uint32_t* aFboId
,
166 wr::DeviceIntRect aDirtyRect
,
167 wr::DeviceIntRect aValidRect
) override
;
168 void Unbind() override
;
171 void InsertFrameDoneSync();
173 bool InitDefaultFramebuffer(const gfx::IntRect
& aBounds
) override
;
174 void DoSwap() override
;
175 void DoFlush() override
;
177 RefPtr
<gl::GLContext
> mGL
;
179 // Used to apply back-pressure in WaitForGPU().
180 GLsync mPreviousFrameDoneSync
= nullptr;
181 GLsync mThisFrameDoneSync
= nullptr;
184 // RenderCompositorNativeSWGL is a NativeLayer compositor that only
185 // deals with mapping the underlying buffer for SWGL usage of a tile.
186 class RenderCompositorNativeSWGL
: public RenderCompositorNative
{
188 static UniquePtr
<RenderCompositor
> Create(
189 const RefPtr
<widget::CompositorWidget
>& aWidget
, nsACString
& aError
);
191 RenderCompositorNativeSWGL(const RefPtr
<widget::CompositorWidget
>& aWidget
,
193 virtual ~RenderCompositorNativeSWGL();
195 void* swgl() const override
{ return mContext
; }
197 bool MakeCurrent() override
;
199 void CancelFrame() override
;
201 layers::WebRenderBackend
BackendType() const override
{
202 return layers::WebRenderBackend::SOFTWARE
;
205 // Maps an underlying layer and sets aData to the top left pixel of
206 // aValidRect. The row stride is set to aStride, note this doesn't
207 // mean there are always aStride bytes available per row (the
208 // last row will fall short if aValidRect is not at X==0).
209 bool MapTile(wr::NativeTileId aId
, wr::DeviceIntRect aDirtyRect
,
210 wr::DeviceIntRect aValidRect
, void** aData
,
211 int32_t* aStride
) override
;
212 void UnmapTile() override
;
215 bool InitDefaultFramebuffer(const gfx::IntRect
& aBounds
) override
;
216 void DoSwap() override
;
218 bool MapNativeLayer(layers::NativeLayer
* aLayer
,
219 const gfx::IntRect
& aDirtyRect
,
220 const gfx::IntRect
& aValidRect
);
221 void UnmapNativeLayer();
223 void* mContext
= nullptr;
224 RefPtr
<gfx::DrawTarget
> mLayerTarget
;
225 uint8_t* mLayerData
= nullptr;
226 uint8_t* mLayerValidRectData
= nullptr;
227 int32_t mLayerStride
= 0;
231 } // namespace mozilla