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_PAINTING_WINDOWRENDERER_H
8 #define MOZILLA_PAINTING_WINDOWRENDERER_H
10 #include "mozilla/webrender/webrender_ffi.h"
11 #include "mozilla/layers/LayersTypes.h"
12 #include "mozilla/dom/Animation.h" // for Animation
13 #include "mozilla/layers/ScrollableLayerGuid.h" // for ScrollableLayerGuid, ScrollableLayerGuid::ViewID
14 #include "mozilla/ScrollPositionUpdate.h" // for ScrollPositionUpdate
15 #include "nsRefPtrHashtable.h" // for nsRefPtrHashtable
16 #include "gfxContext.h"
21 class WebRenderLayerManager
;
22 class KnowsCompositor
;
23 class CompositorBridgeChild
;
24 class FrameUniformityData
;
25 class PersistentBufferProvider
;
27 class FallbackRenderer
;
28 class nsDisplayListBuilder
;
34 * Record (and return) frame-intervals and paint-times for frames which were
35 * presented between calling StartFrameTimeRecording and
36 * StopFrameTimeRecording.
38 * - Uses a cyclic buffer and serves concurrent consumers, so if Stop is
40 * (elements were overwritten since Start), result is considered invalid
42 * - Buffer is capable of holding 10 seconds @ 60fps (or more if frames were
44 * Can be changed (up to 1 hour) via pref:
45 * toolkit.framesRecording.bufferSize.
46 * - Note: the first frame-interval may be longer than expected because last
48 * might have been presented some time before calling
49 * StartFrameTimeRecording.
53 * Returns a handle which represents current recording start position.
55 virtual uint32_t StartFrameTimeRecording(int32_t aBufferSize
);
58 * Clears, then populates aFrameIntervals with the recorded frame timing
59 * data. The array will be empty if data was overwritten since
60 * aStartIndex was obtained.
62 virtual void StopFrameTimeRecording(uint32_t aStartIndex
,
63 nsTArray
<float>& aFrameIntervals
);
68 struct FramesTimingRecording
{
69 // Stores state and data for frame intervals and paint times recording.
70 // see LayerManager::StartFrameTimeRecording() at Layers.cpp for more
72 FramesTimingRecording()
75 mCurrentRunStartIndex(0),
77 nsTArray
<float> mIntervals
;
78 TimeStamp mLastFrameTime
;
80 uint32_t mLatestStartIndex
;
81 uint32_t mCurrentRunStartIndex
;
84 FramesTimingRecording mRecording
;
88 * WindowRenderer is the retained rendering object owned by an nsIWidget for
89 * drawing the contents of that window, the role previously handled by
92 * It can be WebRender, (deprecated) Layers, or an immediate-mode
95 * The intention is for LayerManager to be removed entirely in the near future,
96 * with WebRender inheriting directly from this class. It is likely that more
97 * cleanup can be done once that happens.
99 class WindowRenderer
: public FrameRecorder
{
100 NS_INLINE_DECL_REFCOUNTING(WindowRenderer
)
103 // Cast to implementation types.
104 virtual layers::WebRenderLayerManager
* AsWebRender() { return nullptr; }
105 virtual FallbackRenderer
* AsFallback() { return nullptr; }
107 // Required functionality
110 * Start a new transaction. Nested transactions are not allowed so
111 * there must be no transaction currently in progress.
112 * This transaction will update the state of the window from which
113 * this LayerManager was obtained.
115 virtual bool BeginTransaction(const nsCString
& aURL
= nsCString()) = 0;
117 enum EndTransactionFlags
{
119 END_NO_IMMEDIATE_REDRAW
= 1 << 0, // Do not perform the drawing phase
121 1 << 1, // Do not composite after drawing painted layer contents.
122 END_NO_REMOTE_COMPOSITE
= 1 << 2 // Do not schedule a composition with a
123 // remote Compositor, if one exists.
127 * Attempts to end an "empty transaction". There must have been no
128 * changes to the layer tree since the BeginTransaction().
129 * It's possible for this to fail; PaintedLayers may need to be updated
130 * due to VRAM data being lost, for example. In such cases this method
131 * returns false, and the caller must proceed with a normal layer tree
132 * update and EndTransaction.
134 virtual bool EndEmptyTransaction(
135 EndTransactionFlags aFlags
= END_DEFAULT
) = 0;
137 virtual void Destroy() {}
140 * Type of layer manager this is. This is to be used sparsely in order to
141 * avoid a lot of Layers backend specific code. It should be used only when
142 * Layers backend specific functionality is necessary.
144 virtual layers::LayersBackend
GetBackendType() = 0;
147 * Type of layers backend that will be used to composite this layer tree.
148 * When compositing is done remotely, then this returns the layers type
151 virtual layers::LayersBackend
GetCompositorBackendType() {
152 return GetBackendType();
156 * Checks if we need to invalidate the OS widget to trigger
157 * painting when updating this renderer.
159 virtual bool NeedsWidgetInvalidation() { return true; }
162 * Make sure that the previous transaction has been entirely
165 * Note: This may sychronously wait on a remote compositor
166 * to complete rendering.
168 virtual void FlushRendering(wr::RenderReasons aReasons
) {}
171 * Make sure that the previous transaction has been
172 * received. This will synchronsly wait on a remote compositor.
174 virtual void WaitOnTransactionProcessed() {}
176 virtual bool IsCompositingCheap() { return true; }
179 * returns the maximum texture size on this layer backend, or INT32_MAX
180 * if there is no maximum
182 virtual int32_t GetMaxTextureSize() const { return INT32_MAX
; }
185 * Return the name of the layer manager's backend.
187 virtual void GetBackendName(nsAString
& aName
) = 0;
189 virtual void GetFrameUniformity(layers::FrameUniformityData
* aOutData
) {}
191 virtual bool AddPendingScrollUpdateForNextTransaction(
192 layers::ScrollableLayerGuid::ViewID aScrollId
,
193 const ScrollPositionUpdate
& aUpdateInfo
) {
198 * Creates a PersistentBufferProvider for use with canvas which is optimized
199 * for inter-operating with this layermanager.
201 virtual already_AddRefed
<layers::PersistentBufferProvider
>
202 CreatePersistentBufferProvider(const mozilla::gfx::IntSize
& aSize
,
203 mozilla::gfx::SurfaceFormat aFormat
,
204 bool aWillReadFrequently
= false);
206 // Helper wrappers around cast to impl and then cast again.
208 virtual layers::KnowsCompositor
* AsKnowsCompositor() { return nullptr; }
210 virtual layers::CompositorBridgeChild
* GetCompositorBridgeChild() {
214 // Provided functionality
216 void AddPartialPrerenderedAnimation(uint64_t aCompositorAnimationId
,
217 dom::Animation
* aAnimation
);
218 void RemovePartialPrerenderedAnimation(uint64_t aCompositorAnimationId
,
219 dom::Animation
* aAnimation
);
220 void UpdatePartialPrerenderedAnimations(
221 const nsTArray
<uint64_t>& aJankedAnimations
);
224 virtual ~WindowRenderer() = default;
226 // Transform animations which are not fully pre-rendered because it's on a
227 // large frame. We need to update the pre-rendered area once after we tried
228 // to composite area which is outside of the pre-rendered area on the
230 nsRefPtrHashtable
<nsUint64HashKey
, dom::Animation
>
231 mPartialPrerenderedAnimations
;
235 * FallbackRenderer is non-retained renderer that acts as a direct wrapper
236 * around calling Paint on the provided DisplayList. This is used for cases
237 * where initializing WebRender is too costly, and we don't need
238 * retaining/invalidation (like small popup windows).
240 * It doesn't support any sort of EmptyTransaction, and only draws during
241 * EndTransaction if a composite is requested (no END_NO_COMPOSITE flag
244 class FallbackRenderer
: public WindowRenderer
{
246 FallbackRenderer
* AsFallback() override
{ return this; }
248 void SetTarget(gfxContext
* aContext
, layers::BufferMode aDoubleBuffering
);
250 bool BeginTransaction(const nsCString
& aURL
= nsCString()) override
;
252 bool EndEmptyTransaction(EndTransactionFlags aFlags
= END_DEFAULT
) override
{
256 layers::LayersBackend
GetBackendType() override
{
257 return layers::LayersBackend::LAYERS_NONE
;
260 virtual void GetBackendName(nsAString
& name
) override
{
261 name
.AssignLiteral("Fallback");
264 bool IsCompositingCheap() override
{ return false; }
266 void EndTransactionWithColor(const nsIntRect
& aRect
,
267 const gfx::DeviceColor
& aColor
);
268 void EndTransactionWithList(nsDisplayListBuilder
* aBuilder
,
269 nsDisplayList
* aList
,
270 int32_t aAppUnitsPerDevPixel
,
271 EndTransactionFlags aFlags
);
274 layers::BufferMode mBufferMode
;
277 } // namespace mozilla
279 #endif /* MOZILLA_PAINTING_WINDOWRENDERER_H */