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_layers_ScreenshotGrabber_h
8 #define mozilla_layers_ScreenshotGrabber_h
10 #include "nsISupportsImpl.h"
11 #include "mozilla/RefPtr.h"
12 #include "mozilla/UniquePtr.h"
13 #include "mozilla/gfx/2D.h"
14 #include "mozilla/gfx/Point.h"
15 #include "mozilla/gfx/Rect.h"
20 namespace profiler_screenshots
{
23 class DownscaleTarget
;
24 class AsyncReadbackBuffer
;
26 class ScreenshotGrabberImpl
;
27 } // namespace profiler_screenshots
30 * Used by various renderers / layer managers to grab snapshots from the window
31 * and submit them to the Gecko profiler.
32 * Doesn't do any work if the profiler is not running or the "screenshots"
33 * feature is not enabled.
34 * Screenshots are scaled down to fit within a fixed size, and read back to
35 * main memory using async readback. Scaling is done in multiple scale-by-0.5x
36 * steps using DownscaleTarget::CopyFrom, and readback is done using
37 * AsyncReadbackBuffers.
39 class ScreenshotGrabber final
{
44 // Scale the contents of aWindow's current render target into an
45 // appropriately sized DownscaleTarget and read its contents into an
46 // AsyncReadbackBuffer. The AsyncReadbackBuffer is not mapped into main
47 // memory until the second call to MaybeProcessQueue() after this call to
48 // MaybeGrabScreenshot().
49 void MaybeGrabScreenshot(profiler_screenshots::Window
& aWindow
,
50 const gfx::IntSize
& aWindowSize
);
52 // Map the contents of any outstanding AsyncReadbackBuffers from previous
53 // composites into main memory and submit each screenshot to the profiler.
54 void MaybeProcessQueue();
56 // Insert a special profiler marker for a composite that didn't do any actual
57 // compositing, so that the profiler knows why no screenshot was taken for
59 void NotifyEmptyFrame();
61 // Destroy all Window-related resources that this class is holding on to.
65 // non-null while ProfilerScreenshots::IsEnabled() returns true
66 UniquePtr
<profiler_screenshots::ScreenshotGrabberImpl
> mImpl
;
69 // Interface definitions.
71 namespace profiler_screenshots
{
75 virtual already_AddRefed
<RenderSource
> GetWindowContents(
76 const gfx::IntSize
& aWindowSize
) = 0;
77 virtual already_AddRefed
<DownscaleTarget
> CreateDownscaleTarget(
78 const gfx::IntSize
& aSize
) = 0;
79 virtual already_AddRefed
<AsyncReadbackBuffer
> CreateAsyncReadbackBuffer(
80 const gfx::IntSize
& aSize
) = 0;
88 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(RenderSource
)
90 const auto& Size() const { return mSize
; }
93 explicit RenderSource(const gfx::IntSize
& aSize
) : mSize(aSize
) {}
94 virtual ~RenderSource() {}
96 const gfx::IntSize mSize
;
99 class DownscaleTarget
{
101 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(DownscaleTarget
)
103 virtual already_AddRefed
<RenderSource
> AsRenderSource() = 0;
105 const auto& Size() const { return mSize
; }
106 virtual bool DownscaleFrom(RenderSource
* aSource
,
107 const gfx::IntRect
& aSourceRect
,
108 const gfx::IntRect
& aDestRect
) = 0;
111 explicit DownscaleTarget(const gfx::IntSize
& aSize
) : mSize(aSize
) {}
112 virtual ~DownscaleTarget() {}
114 const gfx::IntSize mSize
;
117 class AsyncReadbackBuffer
{
119 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(
120 mozilla::layers::profiler_screenshots::AsyncReadbackBuffer
)
122 const auto& Size() const { return mSize
; }
123 virtual void CopyFrom(RenderSource
* aSource
) = 0;
124 virtual bool MapAndCopyInto(gfx::DataSourceSurface
* aSurface
,
125 const gfx::IntSize
& aReadSize
) = 0;
128 explicit AsyncReadbackBuffer(const gfx::IntSize
& aSize
) : mSize(aSize
) {}
129 virtual ~AsyncReadbackBuffer() {}
131 const gfx::IntSize mSize
;
134 } // namespace profiler_screenshots
136 } // namespace layers
137 } // namespace mozilla
139 #endif // mozilla_layers_ScreenshotGrabber_h