1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #include "WebRenderCompositionRecorder.h"
7 #include "mozilla/webrender/RenderThread.h"
13 class RendererRecordedFrame final
: public layers::RecordedFrame
{
15 RendererRecordedFrame(const TimeStamp
& aTimeStamp
, wr::Renderer
* aRenderer
,
16 const wr::RecordedFrameHandle aHandle
,
17 const gfx::IntSize
& aSize
)
18 : RecordedFrame(aTimeStamp
),
23 already_AddRefed
<gfx::DataSourceSurface
> GetSourceSurface() override
{
25 mSurface
= gfx::Factory::CreateDataSourceSurface(
26 mSize
, gfx::SurfaceFormat::B8G8R8A8
, /* aZero = */ false);
28 gfx::DataSourceSurface::ScopedMap
map(mSurface
,
29 gfx::DataSourceSurface::WRITE
);
31 if (!wr_renderer_map_recorded_frame(mRenderer
, mHandle
, map
.GetData(),
32 map
.GetStride() * mSize
.height
,
38 return do_AddRef(mSurface
);
42 wr::Renderer
* mRenderer
;
43 RefPtr
<gfx::DataSourceSurface
> mSurface
;
45 wr::RecordedFrameHandle mHandle
;
48 void WebRenderCompositionRecorder::MaybeRecordFrame(
49 wr::Renderer
* aRenderer
, const wr::WebRenderPipelineInfo
* aFrameEpochs
) {
50 MOZ_ASSERT(wr::RenderThread::IsInRenderThread());
52 if (!aRenderer
|| !aFrameEpochs
|| !DidPaintContent(aFrameEpochs
)) {
56 wr::RecordedFrameHandle handle
{0};
57 gfx::IntSize
size(0, 0);
59 if (wr_renderer_record_frame(aRenderer
, wr::ImageFormat::BGRA8
, &handle
,
60 &size
.width
, &size
.height
)) {
61 RefPtr
<RecordedFrame
> frame
=
62 new RendererRecordedFrame(TimeStamp::Now(), aRenderer
, handle
, size
);
68 bool WebRenderCompositionRecorder::DidPaintContent(
69 const wr::WebRenderPipelineInfo
* aFrameEpochs
) {
70 const wr::WrPipelineInfo
& info
= aFrameEpochs
->Raw();
71 bool didPaintContent
= false;
73 for (const auto& epoch
: info
.epochs
) {
74 const wr::PipelineId pipelineId
= epoch
.pipeline_id
;
76 if (pipelineId
== mRootPipelineId
) {
80 const auto it
= mContentPipelines
.find(AsUint64(pipelineId
));
81 if (it
== mContentPipelines
.end() || it
->second
!= epoch
.epoch
) {
82 // This content pipeline has updated list last render or has newly
84 didPaintContent
= true;
85 mContentPipelines
[AsUint64(pipelineId
)] = epoch
.epoch
;
89 for (const auto& removedPipeline
: info
.removed_pipelines
) {
90 const wr::PipelineId pipelineId
= removedPipeline
.pipeline_id
;
91 if (pipelineId
== mRootPipelineId
) {
94 mContentPipelines
.erase(AsUint64(pipelineId
));
97 return didPaintContent
;
100 } // namespace layers
101 } // namespace mozilla