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 #include "RenderCompositorNative.h"
10 #include "GLContextProvider.h"
11 #include "mozilla/ProfilerLabels.h"
12 #include "mozilla/ProfilerMarkers.h"
13 #include "mozilla/gfx/gfxVars.h"
14 #include "mozilla/gfx/Logging.h"
15 #include "mozilla/layers/CompositionRecorder.h"
16 #include "mozilla/layers/NativeLayer.h"
17 #include "mozilla/layers/SurfacePool.h"
18 #include "mozilla/StaticPrefs_gfx.h"
19 #include "mozilla/webrender/RenderThread.h"
20 #include "mozilla/widget/CompositorWidget.h"
21 #include "RenderCompositorRecordedFrame.h"
23 namespace mozilla::wr
{
25 extern LazyLogModule gRenderThreadLog
;
26 #define LOG(...) MOZ_LOG(gRenderThreadLog, LogLevel::Debug, (__VA_ARGS__))
28 RenderCompositorNative::RenderCompositorNative(
29 const RefPtr
<widget::CompositorWidget
>& aWidget
, gl::GLContext
* aGL
)
30 : RenderCompositor(aWidget
),
31 mNativeLayerRoot(GetWidget()->GetNativeLayerRoot()) {
32 LOG("RenderCompositorNative::RenderCompositorNative()");
34 #if defined(XP_MACOSX) || defined(MOZ_WAYLAND)
35 auto pool
= RenderThread::Get()->SharedSurfacePool();
37 mSurfacePoolHandle
= pool
->GetHandleForGL(aGL
);
40 MOZ_RELEASE_ASSERT(mSurfacePoolHandle
);
43 RenderCompositorNative::~RenderCompositorNative() {
44 LOG("RRenderCompositorNative::~RenderCompositorNative()");
47 mProfilerScreenshotGrabber
.Destroy();
48 mNativeLayerRoot
->SetLayers({});
49 mNativeLayerForEntireWindow
= nullptr;
50 mNativeLayerRootSnapshotter
= nullptr;
51 mNativeLayerRoot
= nullptr;
54 bool RenderCompositorNative::BeginFrame() {
56 gfxCriticalNote
<< "Failed to make render context current, can't draw.";
60 gfx::IntSize bufferSize
= GetBufferSize().ToUnknownSize();
61 if (!ShouldUseNativeCompositor()) {
62 if (bufferSize
.IsEmpty()) {
65 if (mNativeLayerForEntireWindow
&&
66 mNativeLayerForEntireWindow
->GetSize() != bufferSize
) {
67 mNativeLayerRoot
->RemoveLayer(mNativeLayerForEntireWindow
);
68 mNativeLayerForEntireWindow
= nullptr;
70 if (!mNativeLayerForEntireWindow
) {
71 mNativeLayerForEntireWindow
=
72 mNativeLayerRoot
->CreateLayer(bufferSize
, false, mSurfacePoolHandle
);
73 mNativeLayerRoot
->AppendLayer(mNativeLayerForEntireWindow
);
77 gfx::IntRect
bounds({}, bufferSize
);
78 if (!InitDefaultFramebuffer(bounds
)) {
85 RenderedFrameId
RenderCompositorNative::EndFrame(
86 const nsTArray
<DeviceIntRect
>& aDirtyRects
) {
87 RenderedFrameId frameId
= GetNextRenderFrameId();
91 if (mNativeLayerForEntireWindow
) {
92 mNativeLayerForEntireWindow
->NotifySurfaceReady();
93 mNativeLayerRoot
->CommitToScreen();
99 void RenderCompositorNative::Pause() {}
101 bool RenderCompositorNative::Resume() { return true; }
103 inline layers::WebRenderCompositor
RenderCompositorNative::CompositorType()
105 if (gfx::gfxVars::UseWebRenderCompositor()) {
106 #if defined(XP_MACOSX)
107 return layers::WebRenderCompositor::CORE_ANIMATION
;
108 #elif defined(MOZ_WAYLAND)
109 return layers::WebRenderCompositor::WAYLAND
;
112 return layers::WebRenderCompositor::DRAW
;
115 LayoutDeviceIntSize
RenderCompositorNative::GetBufferSize() {
116 return mWidget
->GetClientSize();
119 bool RenderCompositorNative::ShouldUseNativeCompositor() {
120 return gfx::gfxVars::UseWebRenderCompositor();
123 void RenderCompositorNative::GetCompositorCapabilities(
124 CompositorCapabilities
* aCaps
) {
125 RenderCompositor::GetCompositorCapabilities(aCaps
);
126 #if defined(XP_MACOSX)
127 aCaps
->supports_surface_for_backdrop
= !gfx::gfxVars::UseSoftwareWebRender();
131 bool RenderCompositorNative::MaybeReadback(
132 const gfx::IntSize
& aReadbackSize
, const wr::ImageFormat
& aReadbackFormat
,
133 const Range
<uint8_t>& aReadbackBuffer
, bool* aNeedsYFlip
) {
134 if (!ShouldUseNativeCompositor()) {
138 MOZ_RELEASE_ASSERT(aReadbackFormat
== wr::ImageFormat::BGRA8
);
139 if (!mNativeLayerRootSnapshotter
) {
140 mNativeLayerRootSnapshotter
= mNativeLayerRoot
->CreateSnapshotter();
142 if (!mNativeLayerRootSnapshotter
) {
146 bool success
= mNativeLayerRootSnapshotter
->ReadbackPixels(
147 aReadbackSize
, gfx::SurfaceFormat::B8G8R8A8
, aReadbackBuffer
);
149 // ReadbackPixels might have changed the current context. Make sure GL is
160 bool RenderCompositorNative::MaybeRecordFrame(
161 layers::CompositionRecorder
& aRecorder
) {
162 if (!ShouldUseNativeCompositor()) {
166 if (!mNativeLayerRootSnapshotter
) {
167 mNativeLayerRootSnapshotter
= mNativeLayerRoot
->CreateSnapshotter();
170 if (!mNativeLayerRootSnapshotter
) {
174 gfx::IntSize size
= GetBufferSize().ToUnknownSize();
175 RefPtr
<layers::profiler_screenshots::RenderSource
> snapshot
=
176 mNativeLayerRootSnapshotter
->GetWindowContents(size
);
181 RefPtr
<layers::profiler_screenshots::AsyncReadbackBuffer
> buffer
=
182 mNativeLayerRootSnapshotter
->CreateAsyncReadbackBuffer(size
);
183 buffer
->CopyFrom(snapshot
);
185 RefPtr
<layers::RecordedFrame
> frame
=
186 new RenderCompositorRecordedFrame(TimeStamp::Now(), std::move(buffer
));
187 aRecorder
.RecordFrame(frame
);
189 // GetWindowContents might have changed the current context. Make sure our
190 // context is current again.
195 bool RenderCompositorNative::MaybeGrabScreenshot(
196 const gfx::IntSize
& aWindowSize
) {
197 if (!ShouldUseNativeCompositor()) {
201 if (!mNativeLayerRootSnapshotter
) {
202 mNativeLayerRootSnapshotter
= mNativeLayerRoot
->CreateSnapshotter();
205 if (mNativeLayerRootSnapshotter
) {
206 mProfilerScreenshotGrabber
.MaybeGrabScreenshot(*mNativeLayerRootSnapshotter
,
209 // MaybeGrabScreenshot might have changed the current context. Make sure our
210 // context is current again.
217 bool RenderCompositorNative::MaybeProcessScreenshotQueue() {
218 if (!ShouldUseNativeCompositor()) {
222 mProfilerScreenshotGrabber
.MaybeProcessQueue();
224 // MaybeProcessQueue might have changed the current context. Make sure our
225 // context is current again.
231 void RenderCompositorNative::CompositorBeginFrame() {
232 mAddedLayers
.Clear();
233 mAddedTilePixelCount
= 0;
234 mAddedClippedPixelCount
= 0;
235 mBeginFrameTimeStamp
= TimeStamp::Now();
236 mSurfacePoolHandle
->OnBeginFrame();
237 mNativeLayerRoot
->PrepareForCommit();
240 void RenderCompositorNative::CompositorEndFrame() {
241 if (profiler_thread_is_being_profiled_for_markers()) {
242 auto bufferSize
= GetBufferSize();
243 [[maybe_unused
]] uint64_t windowPixelCount
=
244 uint64_t(bufferSize
.width
) * bufferSize
.height
;
245 int nativeLayerCount
= 0;
246 for (const auto& it
: mSurfaces
) {
247 nativeLayerCount
+= int(it
.second
.mNativeLayers
.size());
249 PROFILER_MARKER_TEXT(
250 "WR OS Compositor frame", GRAPHICS
,
251 MarkerTiming::IntervalUntilNowFrom(mBeginFrameTimeStamp
),
252 nsPrintfCString("%d%% painting, %d%% overdraw, %d used "
253 "layers (%d%% memory) + %d unused layers (%d%% memory)",
254 int(mDrawnPixelCount
* 100 / windowPixelCount
),
255 int(mAddedClippedPixelCount
* 100 / windowPixelCount
),
256 int(mAddedLayers
.Length()),
257 int(mAddedTilePixelCount
* 100 / windowPixelCount
),
258 int(nativeLayerCount
- mAddedLayers
.Length()),
259 int((mTotalTilePixelCount
- mAddedTilePixelCount
) *
260 100 / windowPixelCount
)));
262 mDrawnPixelCount
= 0;
266 mNativeLayerRoot
->SetLayers(mAddedLayers
);
267 mNativeLayerRoot
->CommitToScreen();
268 mSurfacePoolHandle
->OnEndFrame();
271 void RenderCompositorNative::BindNativeLayer(wr::NativeTileId aId
,
272 const gfx::IntRect
& aDirtyRect
) {
273 MOZ_RELEASE_ASSERT(!mCurrentlyBoundNativeLayer
);
275 auto surfaceCursor
= mSurfaces
.find(aId
.surface_id
);
276 MOZ_RELEASE_ASSERT(surfaceCursor
!= mSurfaces
.end());
277 Surface
& surface
= surfaceCursor
->second
;
279 auto layerCursor
= surface
.mNativeLayers
.find(TileKey(aId
.x
, aId
.y
));
280 MOZ_RELEASE_ASSERT(layerCursor
!= surface
.mNativeLayers
.end());
281 RefPtr
<layers::NativeLayer
> layer
= layerCursor
->second
;
283 mCurrentlyBoundNativeLayer
= layer
;
285 mDrawnPixelCount
+= aDirtyRect
.Area();
288 void RenderCompositorNative::UnbindNativeLayer() {
289 MOZ_RELEASE_ASSERT(mCurrentlyBoundNativeLayer
);
291 mCurrentlyBoundNativeLayer
->NotifySurfaceReady();
292 mCurrentlyBoundNativeLayer
= nullptr;
295 void RenderCompositorNative::CreateSurface(wr::NativeSurfaceId aId
,
296 wr::DeviceIntPoint aVirtualOffset
,
297 wr::DeviceIntSize aTileSize
,
299 MOZ_RELEASE_ASSERT(mSurfaces
.find(aId
) == mSurfaces
.end());
300 mSurfaces
.insert({aId
, Surface
{aTileSize
, aIsOpaque
}});
303 void RenderCompositorNative::CreateExternalSurface(wr::NativeSurfaceId aId
,
305 MOZ_RELEASE_ASSERT(mSurfaces
.find(aId
) == mSurfaces
.end());
307 RefPtr
<layers::NativeLayer
> layer
=
308 mNativeLayerRoot
->CreateLayerForExternalTexture(aIsOpaque
);
310 Surface surface
{DeviceIntSize
{}, aIsOpaque
};
311 surface
.mIsExternal
= true;
312 surface
.mNativeLayers
.insert({TileKey(0, 0), layer
});
314 mSurfaces
.insert({aId
, std::move(surface
)});
317 void RenderCompositorNative::CreateBackdropSurface(wr::NativeSurfaceId aId
,
319 MOZ_RELEASE_ASSERT(mSurfaces
.find(aId
) == mSurfaces
.end());
321 gfx::DeviceColor
color(aColor
.r
, aColor
.g
, aColor
.b
, aColor
.a
);
322 RefPtr
<layers::NativeLayer
> layer
=
323 mNativeLayerRoot
->CreateLayerForColor(color
);
325 Surface surface
{DeviceIntSize
{}, (aColor
.a
>= 1.0f
)};
326 surface
.mNativeLayers
.insert({TileKey(0, 0), layer
});
328 mSurfaces
.insert({aId
, std::move(surface
)});
331 void RenderCompositorNative::AttachExternalImage(
332 wr::NativeSurfaceId aId
, wr::ExternalImageId aExternalImage
) {
333 RenderTextureHost
* image
=
334 RenderThread::Get()->GetRenderTexture(aExternalImage
);
335 MOZ_RELEASE_ASSERT(image
);
337 auto surfaceCursor
= mSurfaces
.find(aId
);
338 MOZ_RELEASE_ASSERT(surfaceCursor
!= mSurfaces
.end());
340 Surface
& surface
= surfaceCursor
->second
;
341 MOZ_RELEASE_ASSERT(surface
.mNativeLayers
.size() == 1);
342 MOZ_RELEASE_ASSERT(surface
.mIsExternal
);
343 surface
.mNativeLayers
.begin()->second
->AttachExternalImage(image
);
346 void RenderCompositorNative::DestroySurface(NativeSurfaceId aId
) {
347 auto surfaceCursor
= mSurfaces
.find(aId
);
348 MOZ_RELEASE_ASSERT(surfaceCursor
!= mSurfaces
.end());
350 Surface
& surface
= surfaceCursor
->second
;
351 if (!surface
.mIsExternal
) {
352 for (const auto& iter
: surface
.mNativeLayers
) {
353 mTotalTilePixelCount
-= gfx::IntRect({}, iter
.second
->GetSize()).Area();
357 mSurfaces
.erase(surfaceCursor
);
360 void RenderCompositorNative::CreateTile(wr::NativeSurfaceId aId
, int aX
,
362 auto surfaceCursor
= mSurfaces
.find(aId
);
363 MOZ_RELEASE_ASSERT(surfaceCursor
!= mSurfaces
.end());
364 Surface
& surface
= surfaceCursor
->second
;
365 MOZ_RELEASE_ASSERT(!surface
.mIsExternal
);
367 RefPtr
<layers::NativeLayer
> layer
= mNativeLayerRoot
->CreateLayer(
368 surface
.TileSize(), surface
.mIsOpaque
, mSurfacePoolHandle
);
369 surface
.mNativeLayers
.insert({TileKey(aX
, aY
), layer
});
370 mTotalTilePixelCount
+= gfx::IntRect({}, layer
->GetSize()).Area();
373 void RenderCompositorNative::DestroyTile(wr::NativeSurfaceId aId
, int aX
,
375 auto surfaceCursor
= mSurfaces
.find(aId
);
376 MOZ_RELEASE_ASSERT(surfaceCursor
!= mSurfaces
.end());
377 Surface
& surface
= surfaceCursor
->second
;
378 MOZ_RELEASE_ASSERT(!surface
.mIsExternal
);
380 auto layerCursor
= surface
.mNativeLayers
.find(TileKey(aX
, aY
));
381 MOZ_RELEASE_ASSERT(layerCursor
!= surface
.mNativeLayers
.end());
382 RefPtr
<layers::NativeLayer
> layer
= std::move(layerCursor
->second
);
383 surface
.mNativeLayers
.erase(layerCursor
);
384 mTotalTilePixelCount
-= gfx::IntRect({}, layer
->GetSize()).Area();
386 // If the layer is currently present in mNativeLayerRoot, it will be destroyed
387 // once CompositorEndFrame() replaces mNativeLayerRoot's layers and drops that
388 // reference. So until that happens, the layer still needs to hold on to its
389 // front buffer. However, we can tell it to drop its back buffers now, because
390 // we know that we will never draw to it again.
391 // Dropping the back buffers now puts them back in the surface pool, so those
392 // surfaces can be immediately re-used for drawing in other layers in the
394 layer
->DiscardBackbuffers();
397 gfx::SamplingFilter
ToSamplingFilter(wr::ImageRendering aImageRendering
) {
398 if (aImageRendering
== wr::ImageRendering::Auto
) {
399 return gfx::SamplingFilter::LINEAR
;
401 return gfx::SamplingFilter::POINT
;
404 void RenderCompositorNative::AddSurface(
405 wr::NativeSurfaceId aId
, const wr::CompositorSurfaceTransform
& aTransform
,
406 wr::DeviceIntRect aClipRect
, wr::ImageRendering aImageRendering
) {
407 MOZ_RELEASE_ASSERT(!mCurrentlyBoundNativeLayer
);
409 auto surfaceCursor
= mSurfaces
.find(aId
);
410 MOZ_RELEASE_ASSERT(surfaceCursor
!= mSurfaces
.end());
411 const Surface
& surface
= surfaceCursor
->second
;
413 float sx
= aTransform
.scale
.x
;
414 float sy
= aTransform
.scale
.y
;
415 float tx
= aTransform
.offset
.x
;
416 float ty
= aTransform
.offset
.y
;
417 gfx::Matrix4x4
transform(sx
, 0.0, 0.0, 0.0, 0.0, sy
, 0.0, 0.0, 0.0, 0.0, 1.0,
418 0.0, tx
, ty
, 0.0, 1.0);
420 for (auto it
= surface
.mNativeLayers
.begin();
421 it
!= surface
.mNativeLayers
.end(); ++it
) {
422 RefPtr
<layers::NativeLayer
> layer
= it
->second
;
423 gfx::IntSize layerSize
= layer
->GetSize();
424 gfx::IntPoint
layerPosition(surface
.mTileSize
.width
* it
->first
.mX
,
425 surface
.mTileSize
.height
* it
->first
.mY
);
426 layer
->SetPosition(layerPosition
);
427 gfx::IntRect
clipRect(aClipRect
.min
.x
, aClipRect
.min
.y
, aClipRect
.width(),
429 layer
->SetClipRect(Some(clipRect
));
430 layer
->SetTransform(transform
);
431 layer
->SetSamplingFilter(ToSamplingFilter(aImageRendering
));
432 mAddedLayers
.AppendElement(layer
);
434 if (!surface
.mIsExternal
) {
435 mAddedTilePixelCount
+= layerSize
.width
* layerSize
.height
;
437 gfx::Rect r
= transform
.TransformBounds(
438 gfx::Rect(layer
->CurrentSurfaceDisplayRect()));
439 gfx::IntRect visibleRect
=
440 clipRect
.Intersect(RoundedToInt(r
) + layerPosition
);
441 mAddedClippedPixelCount
+= visibleRect
.Area();
446 UniquePtr
<RenderCompositor
> RenderCompositorNativeOGL::Create(
447 const RefPtr
<widget::CompositorWidget
>& aWidget
, nsACString
& aError
) {
448 RefPtr
<gl::GLContext
> gl
= RenderThread::Get()->SingletonGL();
450 gl
= gl::GLContextProvider::CreateForCompositorWidget(
451 aWidget
, /* aHardwareWebRender */ true, /* aForceAccelerated */ true);
452 RenderThread::MaybeEnableGLDebugMessage(gl
);
454 if (!gl
|| !gl
->MakeCurrent()) {
455 gfxCriticalNote
<< "Failed GL context creation for WebRender: "
456 << gfx::hexa(gl
.get());
459 return MakeUnique
<RenderCompositorNativeOGL
>(aWidget
, std::move(gl
));
462 RenderCompositorNativeOGL::RenderCompositorNativeOGL(
463 const RefPtr
<widget::CompositorWidget
>& aWidget
,
464 RefPtr
<gl::GLContext
>&& aGL
)
465 : RenderCompositorNative(aWidget
, aGL
), mGL(aGL
) {
469 RenderCompositorNativeOGL::~RenderCompositorNativeOGL() {
470 if (!mGL
->MakeCurrent()) {
472 << "Failed to make render context current during destroying.";
474 mPreviousFrameDoneSync
= nullptr;
475 mThisFrameDoneSync
= nullptr;
479 if (mPreviousFrameDoneSync
) {
480 mGL
->fDeleteSync(mPreviousFrameDoneSync
);
482 if (mThisFrameDoneSync
) {
483 mGL
->fDeleteSync(mThisFrameDoneSync
);
487 bool RenderCompositorNativeOGL::InitDefaultFramebuffer(
488 const gfx::IntRect
& aBounds
) {
489 if (mNativeLayerForEntireWindow
) {
490 Maybe
<GLuint
> fbo
= mNativeLayerForEntireWindow
->NextSurfaceAsFramebuffer(
491 aBounds
, aBounds
, true);
495 mGL
->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER
, *fbo
);
497 mGL
->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER
, mGL
->GetDefaultFramebuffer());
502 void RenderCompositorNativeOGL::DoSwap() {
503 InsertFrameDoneSync();
504 if (mNativeLayerForEntireWindow
) {
509 void RenderCompositorNativeOGL::DoFlush() { mGL
->fFlush(); }
511 void RenderCompositorNativeOGL::InsertFrameDoneSync() {
513 // Only do this on macOS.
514 // On other platforms, SwapBuffers automatically applies back-pressure.
515 if (mThisFrameDoneSync
) {
516 mGL
->fDeleteSync(mThisFrameDoneSync
);
518 mThisFrameDoneSync
= mGL
->fFenceSync(LOCAL_GL_SYNC_GPU_COMMANDS_COMPLETE
, 0);
522 bool RenderCompositorNativeOGL::WaitForGPU() {
523 if (mPreviousFrameDoneSync
) {
524 AUTO_PROFILER_LABEL("Waiting for GPU to finish previous frame", GRAPHICS
);
525 mGL
->fClientWaitSync(mPreviousFrameDoneSync
,
526 LOCAL_GL_SYNC_FLUSH_COMMANDS_BIT
,
527 LOCAL_GL_TIMEOUT_IGNORED
);
528 mGL
->fDeleteSync(mPreviousFrameDoneSync
);
530 mPreviousFrameDoneSync
= mThisFrameDoneSync
;
531 mThisFrameDoneSync
= nullptr;
536 void RenderCompositorNativeOGL::Bind(wr::NativeTileId aId
,
537 wr::DeviceIntPoint
* aOffset
,
539 wr::DeviceIntRect aDirtyRect
,
540 wr::DeviceIntRect aValidRect
) {
541 gfx::IntRect
validRect(aValidRect
.min
.x
, aValidRect
.min
.y
, aValidRect
.width(),
542 aValidRect
.height());
543 gfx::IntRect
dirtyRect(aDirtyRect
.min
.x
, aDirtyRect
.min
.y
, aDirtyRect
.width(),
544 aDirtyRect
.height());
546 BindNativeLayer(aId
, dirtyRect
);
548 Maybe
<GLuint
> fbo
= mCurrentlyBoundNativeLayer
->NextSurfaceAsFramebuffer(
549 validRect
, dirtyRect
, true);
552 *aOffset
= wr::DeviceIntPoint
{0, 0};
555 void RenderCompositorNativeOGL::Unbind() {
556 mGL
->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER
, 0);
562 UniquePtr
<RenderCompositor
> RenderCompositorNativeSWGL::Create(
563 const RefPtr
<widget::CompositorWidget
>& aWidget
, nsACString
& aError
) {
564 void* ctx
= wr_swgl_create_context();
566 gfxCriticalNote
<< "Failed SWGL context creation for WebRender";
569 return MakeUnique
<RenderCompositorNativeSWGL
>(aWidget
, ctx
);
572 RenderCompositorNativeSWGL::RenderCompositorNativeSWGL(
573 const RefPtr
<widget::CompositorWidget
>& aWidget
, void* aContext
)
574 : RenderCompositorNative(aWidget
), mContext(aContext
) {
575 MOZ_ASSERT(mContext
);
578 RenderCompositorNativeSWGL::~RenderCompositorNativeSWGL() {
579 wr_swgl_destroy_context(mContext
);
582 bool RenderCompositorNativeSWGL::MakeCurrent() {
583 wr_swgl_make_current(mContext
);
587 bool RenderCompositorNativeSWGL::InitDefaultFramebuffer(
588 const gfx::IntRect
& aBounds
) {
589 if (mNativeLayerForEntireWindow
) {
590 if (!MapNativeLayer(mNativeLayerForEntireWindow
, aBounds
, aBounds
)) {
593 wr_swgl_init_default_framebuffer(mContext
, aBounds
.x
, aBounds
.y
,
594 aBounds
.width
, aBounds
.height
,
595 mLayerStride
, mLayerValidRectData
);
600 void RenderCompositorNativeSWGL::CancelFrame() {
601 if (mNativeLayerForEntireWindow
&& mLayerTarget
) {
602 wr_swgl_init_default_framebuffer(mContext
, 0, 0, 0, 0, 0, nullptr);
607 void RenderCompositorNativeSWGL::DoSwap() {
608 if (mNativeLayerForEntireWindow
&& mLayerTarget
) {
609 wr_swgl_init_default_framebuffer(mContext
, 0, 0, 0, 0, 0, nullptr);
614 bool RenderCompositorNativeSWGL::MapNativeLayer(
615 layers::NativeLayer
* aLayer
, const gfx::IntRect
& aDirtyRect
,
616 const gfx::IntRect
& aValidRect
) {
617 uint8_t* data
= nullptr;
620 gfx::SurfaceFormat format
= gfx::SurfaceFormat::UNKNOWN
;
621 RefPtr
<gfx::DrawTarget
> dt
= aLayer
->NextSurfaceAsDrawTarget(
622 aValidRect
, gfx::IntRegion(aDirtyRect
), gfx::BackendType::SKIA
);
623 if (!dt
|| !dt
->LockBits(&data
, &size
, &stride
, &format
)) {
626 MOZ_ASSERT(format
== gfx::SurfaceFormat::B8G8R8A8
||
627 format
== gfx::SurfaceFormat::B8G8R8X8
);
628 mLayerTarget
= std::move(dt
);
630 mLayerValidRectData
= data
+ aValidRect
.y
* stride
+ aValidRect
.x
* 4;
631 mLayerStride
= stride
;
635 void RenderCompositorNativeSWGL::UnmapNativeLayer() {
636 MOZ_ASSERT(mLayerTarget
&& mLayerData
);
637 mLayerTarget
->ReleaseBits(mLayerData
);
638 mLayerTarget
= nullptr;
639 mLayerData
= nullptr;
640 mLayerValidRectData
= nullptr;
644 bool RenderCompositorNativeSWGL::MapTile(wr::NativeTileId aId
,
645 wr::DeviceIntRect aDirtyRect
,
646 wr::DeviceIntRect aValidRect
,
647 void** aData
, int32_t* aStride
) {
648 if (mNativeLayerForEntireWindow
) {
651 gfx::IntRect
dirtyRect(aDirtyRect
.min
.x
, aDirtyRect
.min
.y
, aDirtyRect
.width(),
652 aDirtyRect
.height());
653 gfx::IntRect
validRect(aValidRect
.min
.x
, aValidRect
.min
.y
, aValidRect
.width(),
654 aValidRect
.height());
655 BindNativeLayer(aId
, dirtyRect
);
656 if (!MapNativeLayer(mCurrentlyBoundNativeLayer
, dirtyRect
, validRect
)) {
660 *aData
= mLayerValidRectData
;
661 *aStride
= mLayerStride
;
665 void RenderCompositorNativeSWGL::UnmapTile() {
666 if (!mNativeLayerForEntireWindow
&& mCurrentlyBoundNativeLayer
) {
672 } // namespace mozilla::wr