RenderCompositorNative.h (8869B)
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/. */ 6 7 #ifndef MOZILLA_GFX_RENDERCOMPOSITOR_NATIVE_H 8 #define MOZILLA_GFX_RENDERCOMPOSITOR_NATIVE_H 9 10 #include <deque> 11 #include <unordered_map> 12 13 #include "GLTypes.h" 14 #include "mozilla/HashFunctions.h" 15 #include "mozilla/layers/ScreenshotGrabber.h" 16 #include "mozilla/webrender/RenderCompositor.h" 17 #include "mozilla/TimeStamp.h" 18 19 namespace mozilla { 20 21 namespace layers { 22 class GpuFence; 23 class NativeLayerRootSnapshotter; 24 class NativeLayerRoot; 25 class NativeLayer; 26 class SurfacePoolHandle; 27 } // namespace layers 28 29 namespace wr { 30 31 // RenderCompositorNative is a skeleton class for implementing compositors 32 // backed by NativeLayer surfaces and tiles. This is not meant to be directly 33 // instantiated and is instead derived for various use-cases such as OpenGL or 34 // SWGL. 35 class RenderCompositorNative : public RenderCompositor { 36 public: 37 virtual ~RenderCompositorNative(); 38 39 bool BeginFrame() override; 40 RenderedFrameId EndFrame(const nsTArray<DeviceIntRect>& aDirtyRects) final; 41 void Pause() override; 42 bool Resume() override; 43 44 layers::WebRenderCompositor CompositorType() const override; 45 46 LayoutDeviceIntSize GetBufferSize() override; 47 48 bool ShouldUseNativeCompositor() override; 49 void GetCompositorCapabilities(CompositorCapabilities* aCaps) override; 50 51 bool SurfaceOriginIsTopLeft() override { return true; } 52 53 // Does the readback for the ShouldUseNativeCompositor() case. 54 bool MaybeReadback(const gfx::IntSize& aReadbackSize, 55 const wr::ImageFormat& aReadbackFormat, 56 const Range<uint8_t>& aReadbackBuffer, 57 bool* aNeedsYFlip) override; 58 bool MaybeRecordFrame(layers::CompositionRecorder& aRecorder) override; 59 bool MaybeGrabScreenshot(const gfx::IntSize& aWindowSize) override; 60 bool MaybeProcessScreenshotQueue() override; 61 62 void WaitUntilPresentationFlushed() override; 63 64 // Interface for wr::Compositor 65 void CompositorBeginFrame() override; 66 void CompositorEndFrame() override; 67 void CreateSurface(wr::NativeSurfaceId aId, wr::DeviceIntPoint aVirtualOffset, 68 wr::DeviceIntSize aTileSize, bool aIsOpaque) override; 69 void CreateExternalSurface(wr::NativeSurfaceId aId, bool aIsOpaque) override; 70 void CreateBackdropSurface(wr::NativeSurfaceId aId, 71 wr::ColorF aColor) override; 72 void DestroySurface(NativeSurfaceId aId) override; 73 void CreateTile(wr::NativeSurfaceId aId, int32_t aX, int32_t aY) override; 74 void DestroyTile(wr::NativeSurfaceId aId, int32_t aX, int32_t aY) override; 75 void AttachExternalImage(wr::NativeSurfaceId aId, 76 wr::ExternalImageId aExternalImage) override; 77 void AddSurface(wr::NativeSurfaceId aId, 78 const wr::CompositorSurfaceTransform& aTransform, 79 wr::DeviceIntRect aClipRect, 80 wr::ImageRendering aImageRendering, 81 wr::DeviceIntRect aRoundedClipRect, 82 wr::ClipRadius aClipRadius) override; 83 84 struct TileKey { 85 TileKey(int32_t aX, int32_t aY) : mX(aX), mY(aY) {} 86 87 int32_t mX; 88 int32_t mY; 89 }; 90 91 protected: 92 explicit RenderCompositorNative( 93 const RefPtr<widget::CompositorWidget>& aWidget, 94 gl::GLContext* aGL = nullptr); 95 96 virtual bool InitDefaultFramebuffer(const gfx::IntRect& aBounds) = 0; 97 virtual void DoSwap() = 0; 98 virtual void DoFlush() {} 99 100 void BindNativeLayer(wr::NativeTileId aId, const gfx::IntRect& aDirtyRect); 101 void UnbindNativeLayer(); 102 103 // Can be null. 104 RefPtr<layers::NativeLayerRoot> mNativeLayerRoot; 105 UniquePtr<layers::NativeLayerRootSnapshotter> mNativeLayerRootSnapshotter; 106 layers::ScreenshotGrabber mProfilerScreenshotGrabber; 107 RefPtr<layers::NativeLayer> mNativeLayerForEntireWindow; 108 RefPtr<layers::SurfacePoolHandle> mSurfacePoolHandle; 109 110 struct TileKeyHashFn { 111 std::size_t operator()(const TileKey& aId) const { 112 return HashGeneric(aId.mX, aId.mY); 113 } 114 }; 115 116 struct Surface { 117 Surface(wr::DeviceIntSize aTileSize, bool aIsOpaque); 118 ~Surface(); 119 120 gfx::IntSize TileSize() const { 121 return gfx::IntSize(mTileSize.width, mTileSize.height); 122 } 123 124 // External images can change size depending on which image 125 // is attached, so mTileSize will be 0,0 when mIsExternal 126 // is true. 127 wr::DeviceIntSize mTileSize; 128 bool mIsOpaque; 129 bool mIsExternal = false; 130 std::unordered_map<TileKey, RefPtr<layers::NativeLayer>, TileKeyHashFn> 131 mNativeLayers; 132 }; 133 134 struct SurfaceIdHashFn { 135 std::size_t operator()(const wr::NativeSurfaceId& aId) const { 136 return HashGeneric(wr::AsUint64(aId)); 137 } 138 }; 139 140 // Used in native compositor mode: 141 RefPtr<layers::NativeLayer> mCurrentlyBoundNativeLayer; 142 nsTArray<RefPtr<layers::NativeLayer>> mAddedLayers; 143 uint64_t mTotalTilePixelCount = 0; 144 uint64_t mAddedTilePixelCount = 0; 145 uint64_t mAddedClippedPixelCount = 0; 146 uint64_t mDrawnPixelCount = 0; 147 gfx::IntRect mVisibleBounds; 148 std::unordered_map<wr::NativeSurfaceId, Surface, SurfaceIdHashFn> mSurfaces; 149 TimeStamp mBeginFrameTimeStamp; 150 std::deque<RefPtr<layers::GpuFence>> mPendingGpuFeces; 151 }; 152 153 static inline bool operator==(const RenderCompositorNative::TileKey& a0, 154 const RenderCompositorNative::TileKey& a1) { 155 return a0.mX == a1.mX && a0.mY == a1.mY; 156 } 157 158 // RenderCompositorNativeOGL is a NativeLayer compositor that exposes an 159 // OpenGL framebuffer for the respective NativeLayer bound to each tile. 160 class RenderCompositorNativeOGL : public RenderCompositorNative { 161 public: 162 static UniquePtr<RenderCompositor> Create( 163 const RefPtr<widget::CompositorWidget>& aWidget, nsACString& aError); 164 165 RenderCompositorNativeOGL(const RefPtr<widget::CompositorWidget>& aWidget, 166 RefPtr<gl::GLContext>&& aGL); 167 virtual ~RenderCompositorNativeOGL(); 168 169 bool WaitForGPU() override; 170 171 gl::GLContext* gl() const override { return mGL; } 172 173 void Bind(wr::NativeTileId aId, wr::DeviceIntPoint* aOffset, uint32_t* aFboId, 174 wr::DeviceIntRect aDirtyRect, 175 wr::DeviceIntRect aValidRect) override; 176 void Unbind() override; 177 178 void AttachExternalImage(wr::NativeSurfaceId aId, 179 wr::ExternalImageId aExternalImage) override; 180 181 protected: 182 void InsertFrameDoneSync(); 183 184 bool InitDefaultFramebuffer(const gfx::IntRect& aBounds) override; 185 void DoSwap() override; 186 void DoFlush() override; 187 188 RefPtr<gl::GLContext> mGL; 189 190 struct BackPressureFences { 191 explicit BackPressureFences( 192 std::deque<RefPtr<layers::GpuFence>>&& aGpuFeces) 193 : mGpuFeces(std::move(aGpuFeces)) {} 194 195 GLsync mSync = nullptr; 196 std::deque<RefPtr<layers::GpuFence>> mGpuFeces; 197 }; 198 199 // Used to apply back-pressure in WaitForGPU(). 200 UniquePtr<BackPressureFences> mPreviousFrameDoneFences; 201 UniquePtr<BackPressureFences> mThisFrameDoneFences; 202 }; 203 204 // RenderCompositorNativeSWGL is a NativeLayer compositor that only 205 // deals with mapping the underlying buffer for SWGL usage of a tile. 206 class RenderCompositorNativeSWGL : public RenderCompositorNative { 207 public: 208 static UniquePtr<RenderCompositor> Create( 209 const RefPtr<widget::CompositorWidget>& aWidget, nsACString& aError); 210 211 RenderCompositorNativeSWGL(const RefPtr<widget::CompositorWidget>& aWidget, 212 void* aContext); 213 virtual ~RenderCompositorNativeSWGL(); 214 215 void* swgl() const override { return mContext; } 216 217 bool MakeCurrent() override; 218 219 void CancelFrame() override; 220 221 layers::WebRenderBackend BackendType() const override { 222 return layers::WebRenderBackend::SOFTWARE; 223 } 224 225 // Maps an underlying layer and sets aData to the top left pixel of 226 // aValidRect. The row stride is set to aStride, note this doesn't 227 // mean there are always aStride bytes available per row (the 228 // last row will fall short if aValidRect is not at X==0). 229 bool MapTile(wr::NativeTileId aId, wr::DeviceIntRect aDirtyRect, 230 wr::DeviceIntRect aValidRect, void** aData, 231 int32_t* aStride) override; 232 void UnmapTile() override; 233 234 protected: 235 bool InitDefaultFramebuffer(const gfx::IntRect& aBounds) override; 236 void DoSwap() override; 237 238 bool MapNativeLayer(layers::NativeLayer* aLayer, 239 const gfx::IntRect& aDirtyRect, 240 const gfx::IntRect& aValidRect); 241 void UnmapNativeLayer(); 242 243 void* mContext = nullptr; 244 RefPtr<gfx::DrawTarget> mLayerTarget; 245 uint8_t* mLayerData = nullptr; 246 uint8_t* mLayerValidRectData = nullptr; 247 int32_t mLayerStride = 0; 248 }; 249 250 } // namespace wr 251 } // namespace mozilla 252 253 #endif