diff options
Diffstat (limited to 'gfx/webrender_bindings/RendererScreenshotGrabber.cpp')
-rw-r--r-- | gfx/webrender_bindings/RendererScreenshotGrabber.cpp | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/gfx/webrender_bindings/RendererScreenshotGrabber.cpp b/gfx/webrender_bindings/RendererScreenshotGrabber.cpp new file mode 100644 index 0000000000..1d001d4727 --- /dev/null +++ b/gfx/webrender_bindings/RendererScreenshotGrabber.cpp @@ -0,0 +1,104 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "RendererScreenshotGrabber.h" + +#include "RendererOGL.h" + +#include "mozilla/gfx/2D.h" + +using mozilla::layers::ProfilerScreenshots; + +namespace mozilla { +namespace wr { + +RendererScreenshotGrabber::RendererScreenshotGrabber() { + mMaxScreenshotSize = ProfilerScreenshots::ScreenshotSize(); +} + +void RendererScreenshotGrabber::MaybeGrabScreenshot( + RendererOGL* aRendererOGL, const gfx::IntSize& aWindowSize) { + bool isEnabled = + ProfilerScreenshots::IsEnabled() && aRendererOGL->EnsureAsyncScreenshot(); + + if (isEnabled) { + if (!mProfilerScreenshots) { + mProfilerScreenshots = new ProfilerScreenshots(); + } + + GrabScreenshot(aRendererOGL->GetRenderer(), aWindowSize); + } else if (mProfilerScreenshots) { + Destroy(aRendererOGL->GetRenderer()); + } +} + +void RendererScreenshotGrabber::MaybeProcessQueue(RendererOGL* aRendererOGL) { + bool isEnabled = + ProfilerScreenshots::IsEnabled() && aRendererOGL->EnsureAsyncScreenshot(); + + if (isEnabled) { + if (!mProfilerScreenshots) { + mProfilerScreenshots = new ProfilerScreenshots(); + } + + ProcessQueue(aRendererOGL->GetRenderer()); + } else if (mProfilerScreenshots) { + Destroy(aRendererOGL->GetRenderer()); + } +} + +void RendererScreenshotGrabber::Destroy(Renderer* aRenderer) { + mQueue.Clear(); + mCurrentFrameQueueItem = Nothing(); + mProfilerScreenshots = nullptr; + + wr_renderer_release_profiler_structures(aRenderer); +} + +void RendererScreenshotGrabber::GrabScreenshot( + Renderer* aRenderer, const gfx::IntSize& aWindowSize) { + gfx::IntSize screenshotSize; + + AsyncScreenshotHandle handle = wr_renderer_get_screenshot_async( + aRenderer, 0, 0, aWindowSize.width, aWindowSize.height, + mMaxScreenshotSize.width, mMaxScreenshotSize.height, ImageFormat::BGRA8, + &screenshotSize.width, &screenshotSize.height); + + mCurrentFrameQueueItem = Some(QueueItem{ + TimeStamp::Now(), + handle, + screenshotSize, + aWindowSize, + }); +} + +void RendererScreenshotGrabber::ProcessQueue(Renderer* aRenderer) { + for (const auto& item : mQueue) { + mProfilerScreenshots->SubmitScreenshot( + item.mWindowSize, item.mScreenshotSize, item.mTimeStamp, + [&item, aRenderer](gfx::DataSourceSurface* aTargetSurface) { + gfx::DataSourceSurface::ScopedMap map(aTargetSurface, + gfx::DataSourceSurface::WRITE); + int32_t destStride = map.GetStride(); + + bool success = wr_renderer_map_and_recycle_screenshot( + aRenderer, item.mHandle, map.GetData(), + destStride * aTargetSurface->GetSize().height, destStride); + + return success; + }); + } + + mQueue.Clear(); + + if (mCurrentFrameQueueItem) { + mQueue.AppendElement(*mCurrentFrameQueueItem); + mCurrentFrameQueueItem = Nothing(); + } +} + +} // namespace wr +} // namespace mozilla |