/* -*- 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/. */ #ifndef MOZILLA_GFX_RENDERCOMPOSITOR_LAYER_NATIVE_H #define MOZILLA_GFX_RENDERCOMPOSITOR_LAYER_NATIVE_H #include #include #include "GLTypes.h" #include "mozilla/HashFunctions.h" #include "mozilla/layers/ScreenshotGrabber.h" #include "mozilla/webrender/RenderCompositor.h" #include "mozilla/TimeStamp.h" namespace mozilla { namespace layers { class GpuFence; class NativeLayerRootSnapshotter; class NativeLayerRoot; class NativeLayer; class SurfacePoolHandle; } // namespace layers namespace wr { // RenderCompositorLayerNative is a skeleton class for implementing layer // compositors backed by NativeLayer surfaces. This is not meant to be directly // instantiated and is instead derived for various use-cases such as OpenGL. class RenderCompositorLayerNative : public RenderCompositor { public: virtual ~RenderCompositorLayerNative(); bool BeginFrame() override; RenderedFrameId EndFrame(const nsTArray& aDirtyRects) final; void Pause() override; bool Resume() override; layers::WebRenderCompositor CompositorType() const override; LayoutDeviceIntSize GetBufferSize() override; bool ShouldUseNativeCompositor() override; bool ShouldUseLayerCompositor() const override; bool UseLayerCompositor() const override; bool EnableAsyncScreenshot() override; void GetCompositorCapabilities(CompositorCapabilities* aCaps) override; void GetWindowProperties(WindowProperties* aProperties) override; bool SurfaceOriginIsTopLeft() override { return true; } // Does the readback for the ShouldUseNativeCompositor() case. bool MaybeReadback(const gfx::IntSize& aReadbackSize, const wr::ImageFormat& aReadbackFormat, const Range& aReadbackBuffer, bool* aNeedsYFlip) override; bool MaybeRecordFrame(layers::CompositionRecorder& aRecorder) override; bool MaybeGrabScreenshot(const gfx::IntSize& aWindowSize) override; bool MaybeProcessScreenshotQueue() override; void WaitUntilPresentationFlushed() override; // Interface for wr::Compositor void CompositorBeginFrame() override; void CompositorEndFrame() override; void CreateSurface(wr::NativeSurfaceId aId, wr::DeviceIntPoint aVirtualOffset, wr::DeviceIntSize aTileSize, bool aIsOpaque) override; void CreateExternalSurface(wr::NativeSurfaceId aId, bool aIsOpaque) override; void DestroySurface(NativeSurfaceId aId) override; void CreateTile(wr::NativeSurfaceId aId, int32_t aX, int32_t aY) override; void DestroyTile(wr::NativeSurfaceId aId, int32_t aX, int32_t aY) override; void CreateSwapChainSurface(wr::NativeSurfaceId aId, wr::DeviceIntSize aSize, bool aIsOpaque, bool aNeedsSyncDcompCommit) override; void ResizeSwapChainSurface(wr::NativeSurfaceId aId, wr::DeviceIntSize aSize) override; void AttachExternalImage(wr::NativeSurfaceId aId, wr::ExternalImageId aExternalImage) override; void AddSurface(wr::NativeSurfaceId aId, const wr::CompositorSurfaceTransform& aTransform, wr::DeviceIntRect aClipRect, wr::ImageRendering aImageRendering, wr::DeviceIntRect aRoundedClipRect, wr::ClipRadius aClipRadius) override; static gfx::SamplingFilter ToSamplingFilter( wr::ImageRendering aImageRendering); protected: explicit RenderCompositorLayerNative( const RefPtr& aWidget, gl::GLContext* aGL = nullptr); virtual bool InitDefaultFramebuffer() = 0; virtual void DoSwap() = 0; virtual void DoFlush() {} void BindNativeLayer(wr::NativeSurfaceId aId); void UnbindNativeLayer(); RefPtr mNativeLayerRoot; UniquePtr mNativeLayerRootSnapshotter; layers::ScreenshotGrabber mProfilerScreenshotGrabber; RefPtr mSurfacePoolHandle; struct Surface { Surface(wr::DeviceIntSize aSize, bool aIsOpaque); ~Surface(); gfx::IntSize Size() const { return gfx::IntSize(mSize.width, mSize.height); } // External images can change size depending on which image // is attached, so mSize will be 0,0 when mIsExternal // is true. wr::DeviceIntSize mSize; bool mIsOpaque; bool mIsExternal = false; RefPtr mNativeLayer; }; struct SurfaceIdHashFn { std::size_t operator()(const wr::NativeSurfaceId& aId) const { return HashGeneric(wr::AsUint64(aId)); } }; RefPtr mCurrentlyBoundNativeLayer; nsTArray> mAddedLayers; gfx::IntRect mVisibleBounds; std::unordered_map mSurfaces; TimeStamp mBeginFrameTimeStamp; std::deque> mPendingGpuFeces; // Used when platform does not support to take screenshot with multiple // layers. By GetWindowProperties(), it notifies WebRender layer manager to // use single layer for taking screenshot. By EnableAsyncScreenshot(), it // notifies if taking screenshot is ready. bool mEnableAsyncScreenshot = false; // The flag for enabling screenshot with WebRender layer compositor in next // composite. bool mEnableAsyncScreenshotInNextFrame = false; int mCurrentFrame = 0; int mAsyncScreenshotLastFrameUsed = 0; }; // RenderCompositorLayerNativeOGL is a layer compositor that exposes an // OpenGL framebuffer for the respective NativeLayer bound to each Surface. class RenderCompositorLayerNativeOGL : public RenderCompositorLayerNative { public: static UniquePtr Create( const RefPtr& aWidget, nsACString& aError); RenderCompositorLayerNativeOGL( const RefPtr& aWidget, RefPtr&& aGL); virtual ~RenderCompositorLayerNativeOGL(); bool WaitForGPU() override; gl::GLContext* gl() const override { return mGL; } void BindSwapChain(wr::NativeSurfaceId aId, const wr::DeviceIntRect* aDirtyRects, size_t aNumDirtyRects) override; void PresentSwapChain(wr::NativeSurfaceId aId, const wr::DeviceIntRect* aDirtyRects, size_t aNumDirtyRects) override; void AttachExternalImage(wr::NativeSurfaceId aId, wr::ExternalImageId aExternalImage) override; protected: void InsertFrameDoneSync(); bool InitDefaultFramebuffer() override; void DoSwap() override; void DoFlush() override; RefPtr mGL; struct BackPressureFences { explicit BackPressureFences( std::deque>&& aGpuFeces) : mGpuFeces(std::move(aGpuFeces)) {} GLsync mSync = nullptr; std::deque> mGpuFeces; }; // Used to apply back-pressure in WaitForGPU(). UniquePtr mPreviousFrameDoneFences; UniquePtr mThisFrameDoneFences; }; } // namespace wr } // namespace mozilla #endif