--- a/gfx/webrender_bindings/RenderCompositor.cpp
+++ b/gfx/webrender_bindings/RenderCompositor.cpp
@@ -15,16 +15,20 @@
#ifdef XP_WIN
# include "mozilla/webrender/RenderCompositorANGLE.h"
#endif
#if defined(MOZ_WAYLAND) || defined(MOZ_WIDGET_ANDROID)
# include "mozilla/webrender/RenderCompositorEGL.h"
#endif
+#ifdef XP_MACOSX
+# include "mozilla/webrender/RenderCompositorNative.h"
+#endif
+
namespace mozilla {
namespace wr {
void wr_compositor_add_surface(void* aCompositor, wr::NativeSurfaceId aId,
wr::DeviceIntPoint aPosition,
wr::DeviceIntRect aClipRect) {
RenderCompositor* compositor = static_cast<RenderCompositor*>(aCompositor);
compositor->AddSurface(aId, aPosition, aClipRect);
@@ -120,16 +124,19 @@ UniquePtr<RenderCompositor> RenderCompos
if (eglCompositor) {
return eglCompositor;
}
#endif
#if defined(MOZ_WIDGET_ANDROID)
// RenderCompositorOGL is not used on android
return nullptr;
+#elif defined(XP_MACOSX)
+ // Mac uses NativeLayerCA
+ return RenderCompositorNativeOGL::Create(std::move(aWidget));
#else
return RenderCompositorOGL::Create(std::move(aWidget));
#endif
}
RenderCompositor::RenderCompositor(RefPtr<widget::CompositorWidget>&& aWidget)
: mWidget(aWidget) {}
copy from gfx/webrender_bindings/RenderCompositorOGL.cpp
copy to gfx/webrender_bindings/RenderCompositorNative.cpp
--- a/gfx/webrender_bindings/RenderCompositorOGL.cpp
+++ b/gfx/webrender_bindings/RenderCompositorNative.cpp
@@ -1,15 +1,15 @@
/* -*- 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 "RenderCompositorOGL.h"
+#include "RenderCompositorNative.h"
#include "GLContext.h"
#include "GLContextProvider.h"
#include "mozilla/gfx/gfxVars.h"
#include "mozilla/layers/SurfacePool.h"
#include "mozilla/StaticPrefs_gfx.h"
#include "mozilla/webrender/RenderThread.h"
#include "mozilla/widget/CompositorWidget.h"
@@ -17,220 +17,251 @@
#ifdef MOZ_GECKO_PROFILER
# include "ProfilerMarkerPayload.h"
#endif
namespace mozilla {
namespace wr {
/* static */
-UniquePtr<RenderCompositor> RenderCompositorOGL::Create(
+UniquePtr<RenderCompositor> RenderCompositorNativeOGL::Create(
RefPtr<widget::CompositorWidget>&& aWidget) {
RefPtr<gl::GLContext> gl = RenderThread::Get()->SharedGL();
if (!gl) {
gl = gl::GLContextProvider::CreateForCompositorWidget(
aWidget, /* aWebRender */ true, /* aForceAccelerated */ true);
RenderThread::MaybeEnableGLDebugMessage(gl);
}
if (!gl || !gl->MakeCurrent()) {
gfxCriticalNote << "Failed GL context creation for WebRender: "
<< gfx::hexa(gl.get());
return nullptr;
}
- return MakeUnique<RenderCompositorOGL>(std::move(gl), std::move(aWidget));
+ return MakeUnique<RenderCompositorNativeOGL>(std::move(aWidget),
+ std::move(gl));
+}
+
+/* static */
+UniquePtr<RenderCompositor> RenderCompositorNativeSWGL::Create(
+ RefPtr<widget::CompositorWidget>&& aWidget) {
+ return MakeUnique<RenderCompositorNativeSWGL>(std::move(aWidget));
}
-RenderCompositorOGL::RenderCompositorOGL(
- RefPtr<gl::GLContext>&& aGL, RefPtr<widget::CompositorWidget>&& aWidget)
+RenderCompositorNative::RenderCompositorNative(
+ RefPtr<widget::CompositorWidget>&& aWidget, gl::GLContext* aGL)
: RenderCompositor(std::move(aWidget)),
- mGL(aGL),
- mNativeLayerRoot(GetWidget()->GetNativeLayerRoot()),
- mPreviousFrameDoneSync(nullptr),
- mThisFrameDoneSync(nullptr) {
- if (mNativeLayerRoot) {
+ mNativeLayerRoot(GetWidget()->GetNativeLayerRoot()) {
#ifdef XP_MACOSX
- auto pool = RenderThread::Get()->SharedSurfacePool();
- if (pool) {
- mSurfacePoolHandle = pool->GetHandleForGL(mGL);
- }
+ auto pool = RenderThread::Get()->SharedSurfacePool();
+ if (pool) {
+ mSurfacePoolHandle = pool->GetHandleForGL(aGL);
+ }
#endif
- MOZ_RELEASE_ASSERT(mSurfacePoolHandle);
- }
+ MOZ_RELEASE_ASSERT(mSurfacePoolHandle);
}
-RenderCompositorOGL::~RenderCompositorOGL() {
- if (mNativeLayerRoot) {
- mNativeLayerRoot->SetLayers({});
- mNativeLayerForEntireWindow = nullptr;
- mNativeLayerRootSnapshotter = nullptr;
- mNativeLayerRoot = nullptr;
- }
+RenderCompositorNative::~RenderCompositorNative() {
+ mNativeLayerRoot->SetLayers({});
+ mNativeLayerForEntireWindow = nullptr;
+ mNativeLayerRootSnapshotter = nullptr;
+ mNativeLayerRoot = nullptr;
+}
- if (mGL && !mGL->MakeCurrent()) {
+RenderCompositorNativeOGL::RenderCompositorNativeOGL(
+ RefPtr<widget::CompositorWidget>&& aWidget, RefPtr<gl::GLContext>&& aGL)
+ : RenderCompositorNative(std::move(aWidget), aGL), mGL(aGL) {
+ MOZ_ASSERT(mGL);
+}
+
+RenderCompositorNativeOGL::~RenderCompositorNativeOGL() {
+ if (!mGL->MakeCurrent()) {
gfxCriticalNote
<< "Failed to make render context current during destroying.";
// Leak resources!
mPreviousFrameDoneSync = nullptr;
mThisFrameDoneSync = nullptr;
return;
}
if (mPreviousFrameDoneSync) {
mGL->fDeleteSync(mPreviousFrameDoneSync);
}
if (mThisFrameDoneSync) {
mGL->fDeleteSync(mThisFrameDoneSync);
}
}
-bool RenderCompositorOGL::BeginFrame() {
- if (mGL && !mGL->MakeCurrent()) {
+RenderCompositorNativeSWGL::RenderCompositorNativeSWGL(
+ RefPtr<widget::CompositorWidget>&& aWidget)
+ : RenderCompositorNative(std::move(aWidget)) {}
+
+bool RenderCompositorNative::BeginFrame() {
+ if (!MakeCurrent()) {
gfxCriticalNote << "Failed to make render context current, can't draw.";
return false;
}
gfx::IntSize bufferSize = GetBufferSize().ToUnknownSize();
- if (mNativeLayerRoot && !ShouldUseNativeCompositor()) {
+ if (!ShouldUseNativeCompositor()) {
if (mNativeLayerForEntireWindow &&
mNativeLayerForEntireWindow->GetSize() != bufferSize) {
mNativeLayerRoot->RemoveLayer(mNativeLayerForEntireWindow);
mNativeLayerForEntireWindow = nullptr;
}
if (!mNativeLayerForEntireWindow) {
mNativeLayerForEntireWindow =
mNativeLayerRoot->CreateLayer(bufferSize, false, mSurfacePoolHandle);
mNativeLayerForEntireWindow->SetSurfaceIsFlipped(true);
mNativeLayerRoot->AppendLayer(mNativeLayerForEntireWindow);
}
}
- if (mNativeLayerForEntireWindow) {
- gfx::IntRect bounds({}, bufferSize);
- if (mGL) {
- Maybe<GLuint> fbo = mNativeLayerForEntireWindow->NextSurfaceAsFramebuffer(
- bounds, bounds, true);
- if (!fbo) {
- return false;
- }
- mGL->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, *fbo);
- } else if (!MapNativeLayer(mNativeLayerForEntireWindow, bounds, bounds)) {
- return false;
- }
- } else if (mGL) {
- mGL->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, mGL->GetDefaultFramebuffer());
+
+ gfx::IntRect bounds({}, bufferSize);
+ if (!InitDefaultFramebuffer(bounds)) {
+ return false;
}
return true;
}
-void RenderCompositorOGL::CancelFrame() {
+bool RenderCompositorNativeOGL::InitDefaultFramebuffer(
+ const gfx::IntRect& aBounds) {
+ if (mNativeLayerForEntireWindow) {
+ Maybe<GLuint> fbo = mNativeLayerForEntireWindow->NextSurfaceAsFramebuffer(
+ aBounds, aBounds, true);
+ if (!fbo) {
+ return false;
+ }
+ mGL->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, *fbo);
+ } else {
+ mGL->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, mGL->GetDefaultFramebuffer());
+ }
+ return true;
+}
+
+bool RenderCompositorNativeSWGL::InitDefaultFramebuffer(
+ const gfx::IntRect& aBounds) {
+ if (mNativeLayerForEntireWindow) {
+ if (!MapNativeLayer(mNativeLayerForEntireWindow, aBounds, aBounds)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+void RenderCompositorNativeSWGL::CancelFrame() {
if (mNativeLayerForEntireWindow && mLayerTarget) {
UnmapNativeLayer();
}
}
-RenderedFrameId RenderCompositorOGL::EndFrame(
+void RenderCompositorNativeOGL::DoSwap() {
+ InsertFrameDoneSync();
+ if (mNativeLayerForEntireWindow) {
+ mGL->fFlush();
+ }
+}
+
+void RenderCompositorNativeSWGL::DoSwap() {
+ if (mNativeLayerForEntireWindow && mLayerTarget) {
+ UnmapNativeLayer();
+ }
+}
+
+RenderedFrameId RenderCompositorNative::EndFrame(
const nsTArray<DeviceIntRect>& aDirtyRects) {
RenderedFrameId frameId = GetNextRenderFrameId();
- if (mGL) {
- InsertFrameDoneSync();
- if (!mNativeLayerRoot) {
- mGL->SwapBuffers();
- } else if (mNativeLayerForEntireWindow) {
- mGL->fFlush();
- }
- } else if (mNativeLayerForEntireWindow && mLayerTarget) {
- UnmapNativeLayer();
- }
+ DoSwap();
if (mNativeLayerForEntireWindow) {
mNativeLayerForEntireWindow->NotifySurfaceReady();
mNativeLayerRoot->CommitToScreen();
}
return frameId;
}
-void RenderCompositorOGL::InsertFrameDoneSync() {
+void RenderCompositorNativeOGL::InsertFrameDoneSync() {
#ifdef XP_MACOSX
// Only do this on macOS.
// On other platforms, SwapBuffers automatically applies back-pressure.
if (mThisFrameDoneSync) {
mGL->fDeleteSync(mThisFrameDoneSync);
}
mThisFrameDoneSync = mGL->fFenceSync(LOCAL_GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
#endif
}
-bool RenderCompositorOGL::WaitForGPU() {
+bool RenderCompositorNativeOGL::WaitForGPU() {
if (mPreviousFrameDoneSync) {
AUTO_PROFILER_LABEL("Waiting for GPU to finish previous frame", GRAPHICS);
mGL->fClientWaitSync(mPreviousFrameDoneSync,
LOCAL_GL_SYNC_FLUSH_COMMANDS_BIT,
LOCAL_GL_TIMEOUT_IGNORED);
mGL->fDeleteSync(mPreviousFrameDoneSync);
}
mPreviousFrameDoneSync = mThisFrameDoneSync;
mThisFrameDoneSync = nullptr;
return true;
}
-void RenderCompositorOGL::Pause() {}
+void RenderCompositorNative::Pause() {}
-bool RenderCompositorOGL::Resume() { return true; }
+bool RenderCompositorNative::Resume() { return true; }
-LayoutDeviceIntSize RenderCompositorOGL::GetBufferSize() {
+LayoutDeviceIntSize RenderCompositorNative::GetBufferSize() {
return mWidget->GetClientSize();
}
-bool RenderCompositorOGL::ShouldUseNativeCompositor() {
- return mNativeLayerRoot && gfx::gfxVars::UseWebRenderCompositor();
+bool RenderCompositorNative::ShouldUseNativeCompositor() {
+ return gfx::gfxVars::UseWebRenderCompositor();
}
-bool RenderCompositorOGL::MaybeReadback(const gfx::IntSize& aReadbackSize,
- const wr::ImageFormat& aReadbackFormat,
- const Range<uint8_t>& aReadbackBuffer) {
+bool RenderCompositorNative::MaybeReadback(
+ const gfx::IntSize& aReadbackSize, const wr::ImageFormat& aReadbackFormat,
+ const Range<uint8_t>& aReadbackBuffer) {
if (!ShouldUseNativeCompositor()) {
return false;
}
MOZ_RELEASE_ASSERT(aReadbackFormat == wr::ImageFormat::BGRA8);
if (!mNativeLayerRootSnapshotter) {
mNativeLayerRootSnapshotter = mNativeLayerRoot->CreateSnapshotter();
}
bool success = mNativeLayerRootSnapshotter->ReadbackPixels(
aReadbackSize, gfx::SurfaceFormat::B8G8R8A8, aReadbackBuffer);
- // ReadbackPixels might have changed the current context. Make sure mGL is
+ // ReadbackPixels might have changed the current context. Make sure GL is
// current again.
- if (mGL) {
- mGL->MakeCurrent();
- }
+ MakeCurrent();
return success;
}
-uint32_t RenderCompositorOGL::GetMaxUpdateRects() {
+uint32_t RenderCompositorNative::GetMaxUpdateRects() {
if (ShouldUseNativeCompositor() &&
StaticPrefs::gfx_webrender_compositor_max_update_rects_AtStartup() > 0) {
return 1;
}
return 0;
}
-void RenderCompositorOGL::CompositorBeginFrame() {
+void RenderCompositorNative::CompositorBeginFrame() {
mAddedLayers.Clear();
mAddedPixelCount = 0;
mAddedClippedPixelCount = 0;
mBeginFrameTimeStamp = TimeStamp::NowUnfuzzed();
mSurfacePoolHandle->OnBeginFrame();
}
-void RenderCompositorOGL::CompositorEndFrame() {
+void RenderCompositorNativeOGL::DoFlush() { mGL->fFlush(); }
+
+void RenderCompositorNative::CompositorEndFrame() {
#ifdef MOZ_GECKO_PROFILER
if (profiler_thread_is_being_profiled()) {
auto bufferSize = GetBufferSize();
uint64_t windowPixelCount = uint64_t(bufferSize.width) * bufferSize.height;
int nativeLayerCount = 0;
for (const auto& it : mSurfaces) {
nativeLayerCount += int(it.second.mNativeLayers.size());
}
@@ -246,81 +277,76 @@ void RenderCompositorOGL::CompositorEndF
int((mTotalPixelCount - mAddedPixelCount) * 100 /
windowPixelCount)),
JS::ProfilingCategoryPair::GRAPHICS, mBeginFrameTimeStamp,
TimeStamp::NowUnfuzzed());
}
#endif
mDrawnPixelCount = 0;
- if (mGL) {
- mGL->fFlush();
- }
+ DoFlush();
mNativeLayerRoot->SetLayers(mAddedLayers);
mNativeLayerRoot->CommitToScreen();
mSurfacePoolHandle->OnEndFrame();
}
-void RenderCompositorOGL::BindNativeLayer(wr::NativeTileId aId,
- wr::DeviceIntRect aDirtyRect,
- wr::DeviceIntRect aValidRect) {
+void RenderCompositorNative::BindNativeLayer(wr::NativeTileId aId,
+ const gfx::IntRect& aDirtyRect) {
MOZ_RELEASE_ASSERT(!mCurrentlyBoundNativeLayer);
auto surfaceCursor = mSurfaces.find(aId.surface_id);
MOZ_RELEASE_ASSERT(surfaceCursor != mSurfaces.end());
Surface& surface = surfaceCursor->second;
auto layerCursor = surface.mNativeLayers.find(TileKey(aId.x, aId.y));
MOZ_RELEASE_ASSERT(layerCursor != surface.mNativeLayers.end());
RefPtr<layers::NativeLayer> layer = layerCursor->second;
- gfx::IntRect dirtyRect(aDirtyRect.origin.x, aDirtyRect.origin.y,
- aDirtyRect.size.width, aDirtyRect.size.height);
-
mCurrentlyBoundNativeLayer = layer;
- mDrawnPixelCount += dirtyRect.Area();
+ mDrawnPixelCount += aDirtyRect.Area();
}
-void RenderCompositorOGL::UnbindNativeLayer() {
+void RenderCompositorNative::UnbindNativeLayer() {
MOZ_RELEASE_ASSERT(mCurrentlyBoundNativeLayer);
mCurrentlyBoundNativeLayer->NotifySurfaceReady();
mCurrentlyBoundNativeLayer = nullptr;
}
-void RenderCompositorOGL::Bind(wr::NativeTileId aId,
- wr::DeviceIntPoint* aOffset, uint32_t* aFboId,
- wr::DeviceIntRect aDirtyRect,
- wr::DeviceIntRect aValidRect) {
- BindNativeLayer(aId, aDirtyRect, aValidRect);
-
+void RenderCompositorNativeOGL::Bind(wr::NativeTileId aId,
+ wr::DeviceIntPoint* aOffset,
+ uint32_t* aFboId,
+ wr::DeviceIntRect aDirtyRect,
+ wr::DeviceIntRect aValidRect) {
gfx::IntRect validRect(aValidRect.origin.x, aValidRect.origin.y,
aValidRect.size.width, aValidRect.size.height);
gfx::IntRect dirtyRect(aDirtyRect.origin.x, aDirtyRect.origin.y,
aDirtyRect.size.width, aDirtyRect.size.height);
+ BindNativeLayer(aId, dirtyRect);
+
Maybe<GLuint> fbo = mCurrentlyBoundNativeLayer->NextSurfaceAsFramebuffer(
validRect, dirtyRect, true);
MOZ_RELEASE_ASSERT(fbo); // TODO: make fallible
*aFboId = *fbo;
*aOffset = wr::DeviceIntPoint{0, 0};
}
-void RenderCompositorOGL::Unbind() {
+void RenderCompositorNativeOGL::Unbind() {
mGL->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, 0);
UnbindNativeLayer();
}
-bool RenderCompositorOGL::MapNativeLayer(layers::NativeLayer* aLayer,
- const gfx::IntRect& aDirtyRect,
- const gfx::IntRect& aValidRect) {
+bool RenderCompositorNativeSWGL::MapNativeLayer(
+ layers::NativeLayer* aLayer, const gfx::IntRect& aDirtyRect,
+ const gfx::IntRect& aValidRect) {
uint8_t* data = nullptr;
gfx::IntSize size;
int32_t stride = 0;
gfx::SurfaceFormat format = gfx::SurfaceFormat::UNKNOWN;
RefPtr<gfx::DrawTarget> dt = aLayer->NextSurfaceAsDrawTarget(
aValidRect, gfx::IntRegion(aDirtyRect), gfx::BackendType::SKIA);
if (!dt || !dt->LockBits(&data, &size, &stride, &format)) {
return false;
@@ -328,93 +354,96 @@ bool RenderCompositorOGL::MapNativeLayer
MOZ_ASSERT(format == gfx::SurfaceFormat::B8G8R8A8 ||
format == gfx::SurfaceFormat::B8G8R8X8);
mLayerTarget = std::move(dt);
mLayerData = data;
mLayerStride = stride;
return true;
}
-void RenderCompositorOGL::UnmapNativeLayer() {
+void RenderCompositorNativeSWGL::UnmapNativeLayer() {
MOZ_ASSERT(mLayerTarget && mLayerData);
mLayerTarget->ReleaseBits(mLayerData);
mLayerTarget = nullptr;
mLayerData = nullptr;
mLayerStride = 0;
}
-bool RenderCompositorOGL::GetMappedBuffer(uint8_t** aData, int32_t* aStride) {
+bool RenderCompositorNativeSWGL::GetMappedBuffer(uint8_t** aData,
+ int32_t* aStride) {
if (mNativeLayerForEntireWindow && mLayerData) {
*aData = mLayerData;
*aStride = mLayerStride;
return true;
}
return false;
}
-bool RenderCompositorOGL::MapTile(wr::NativeTileId aId,
- wr::DeviceIntRect aDirtyRect,
- wr::DeviceIntRect aValidRect,
- void** aData, int32_t* aStride) {
- if (!mNativeLayerRoot || mNativeLayerForEntireWindow) {
+bool RenderCompositorNativeSWGL::MapTile(wr::NativeTileId aId,
+ wr::DeviceIntRect aDirtyRect,
+ wr::DeviceIntRect aValidRect,
+ void** aData, int32_t* aStride) {
+ if (mNativeLayerForEntireWindow) {
return false;
}
- BindNativeLayer(aId, aDirtyRect, aValidRect);
gfx::IntRect dirtyRect(aDirtyRect.origin.x, aDirtyRect.origin.y,
aDirtyRect.size.width, aDirtyRect.size.height);
gfx::IntRect validRect(aValidRect.origin.x, aValidRect.origin.y,
aValidRect.size.width, aValidRect.size.height);
+ BindNativeLayer(aId, dirtyRect);
if (!MapNativeLayer(mCurrentlyBoundNativeLayer, dirtyRect, validRect)) {
UnbindNativeLayer();
return false;
}
*aData = mLayerData;
*aStride = mLayerStride;
return true;
}
-void RenderCompositorOGL::UnmapTile() {
+void RenderCompositorNativeSWGL::UnmapTile() {
if (!mNativeLayerForEntireWindow && mCurrentlyBoundNativeLayer) {
UnmapNativeLayer();
UnbindNativeLayer();
}
}
-void RenderCompositorOGL::CreateSurface(wr::NativeSurfaceId aId,
- wr::DeviceIntPoint aVirtualOffset,
- wr::DeviceIntSize aTileSize,
- bool aIsOpaque) {
+void RenderCompositorNative::CreateSurface(wr::NativeSurfaceId aId,
+ wr::DeviceIntPoint aVirtualOffset,
+ wr::DeviceIntSize aTileSize,
+ bool aIsOpaque) {
MOZ_RELEASE_ASSERT(mSurfaces.find(aId) == mSurfaces.end());
mSurfaces.insert({aId, Surface{aTileSize, aIsOpaque}});
}
-void RenderCompositorOGL::DestroySurface(NativeSurfaceId aId) {
+void RenderCompositorNative::DestroySurface(NativeSurfaceId aId) {
auto surfaceCursor = mSurfaces.find(aId);
MOZ_RELEASE_ASSERT(surfaceCursor != mSurfaces.end());
Surface& surface = surfaceCursor->second;
for (const auto& iter : surface.mNativeLayers) {
mTotalPixelCount -= gfx::IntRect({}, iter.second->GetSize()).Area();
}
mSurfaces.erase(surfaceCursor);
}
-void RenderCompositorOGL::CreateTile(wr::NativeSurfaceId aId, int aX, int aY) {
+void RenderCompositorNative::CreateTile(wr::NativeSurfaceId aId, int aX,
+ int aY) {
auto surfaceCursor = mSurfaces.find(aId);
MOZ_RELEASE_ASSERT(surfaceCursor != mSurfaces.end());
Surface& surface = surfaceCursor->second;
RefPtr<layers::NativeLayer> layer = mNativeLayerRoot->CreateLayer(
surface.TileSize(), surface.mIsOpaque, mSurfacePoolHandle);
surface.mNativeLayers.insert({TileKey(aX, aY), layer});
mTotalPixelCount += gfx::IntRect({}, layer->GetSize()).Area();
}
-void RenderCompositorOGL::DestroyTile(wr::NativeSurfaceId aId, int aX, int aY) {
+void RenderCompositorNative::DestroyTile(wr::NativeSurfaceId aId, int aX,
+ int aY) {
auto surfaceCursor = mSurfaces.find(aId);
MOZ_RELEASE_ASSERT(surfaceCursor != mSurfaces.end());
Surface& surface = surfaceCursor->second;
auto layerCursor = surface.mNativeLayers.find(TileKey(aX, aY));
MOZ_RELEASE_ASSERT(layerCursor != surface.mNativeLayers.end());
RefPtr<layers::NativeLayer> layer = std::move(layerCursor->second);
surface.mNativeLayers.erase(layerCursor);
@@ -426,19 +455,19 @@ void RenderCompositorOGL::DestroyTile(wr
// front buffer. However, we can tell it to drop its back buffers now, because
// we know that we will never draw to it again.
// Dropping the back buffers now puts them back in the surface pool, so those
// surfaces can be immediately re-used for drawing in other layers in the
// current frame.
layer->DiscardBackbuffers();
}
-void RenderCompositorOGL::AddSurface(wr::NativeSurfaceId aId,
- wr::DeviceIntPoint aPosition,
- wr::DeviceIntRect aClipRect) {
+void RenderCompositorNative::AddSurface(wr::NativeSurfaceId aId,
+ wr::DeviceIntPoint aPosition,
+ wr::DeviceIntRect aClipRect) {
MOZ_RELEASE_ASSERT(!mCurrentlyBoundNativeLayer);
auto surfaceCursor = mSurfaces.find(aId);
MOZ_RELEASE_ASSERT(surfaceCursor != mSurfaces.end());
const Surface& surface = surfaceCursor->second;
for (auto it = surface.mNativeLayers.begin();
it != surface.mNativeLayers.end(); ++it) {
@@ -455,17 +484,17 @@ void RenderCompositorOGL::AddSurface(wr:
mAddedPixelCount += layerSize.width * layerSize.height;
gfx::IntRect visibleRect =
clipRect.Intersect(layer->CurrentSurfaceDisplayRect() + layerPosition);
mAddedClippedPixelCount += visibleRect.Area();
}
}
-CompositorCapabilities RenderCompositorOGL::GetCompositorCapabilities() {
+CompositorCapabilities RenderCompositorNative::GetCompositorCapabilities() {
CompositorCapabilities caps;
// CoreAnimation doesn't use virtual surfaces
caps.virtual_surface_size = 0;
return caps;
}
copy from gfx/webrender_bindings/RenderCompositorOGL.h
copy to gfx/webrender_bindings/RenderCompositorNative.h
--- a/gfx/webrender_bindings/RenderCompositorOGL.h
+++ b/gfx/webrender_bindings/RenderCompositorNative.h
@@ -1,75 +1,58 @@
/* -*- 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_OGL_H
-#define MOZILLA_GFX_RENDERCOMPOSITOR_OGL_H
+#ifndef MOZILLA_GFX_RENDERCOMPOSITOR_NATIVE_H
+#define MOZILLA_GFX_RENDERCOMPOSITOR_NATIVE_H
#include "GLTypes.h"
#include "mozilla/webrender/RenderCompositor.h"
#include "mozilla/TimeStamp.h"
namespace mozilla {
namespace layers {
class NativeLayerRootSnapshotter;
class NativeLayerRoot;
class NativeLayer;
class SurfacePoolHandle;
} // namespace layers
namespace wr {
-class RenderCompositorOGL : public RenderCompositor {
+// RenderCompositorNative is a skeleton class for implementing compositors
+// backed by NativeLayer surfaces and tiles. This is not meant to be directly
+// instantiated and is instead derived for various use-cases such as OpenGL or
+// SWGL.
+class RenderCompositorNative : public RenderCompositor {
public:
- static UniquePtr<RenderCompositor> Create(
- RefPtr<widget::CompositorWidget>&& aWidget);
-
- RenderCompositorOGL(RefPtr<gl::GLContext>&& aGL,
- RefPtr<widget::CompositorWidget>&& aWidget);
- virtual ~RenderCompositorOGL();
+ virtual ~RenderCompositorNative();
bool BeginFrame() override;
- void CancelFrame() override;
RenderedFrameId EndFrame(const nsTArray<DeviceIntRect>& aDirtyRects) final;
- bool WaitForGPU() override;
void Pause() override;
bool Resume() override;
- bool GetMappedBuffer(uint8_t** aData, int32_t* aStride) override;
-
- gl::GLContext* gl() const override { return mGL; }
-
- bool UseANGLE() const override { return false; }
-
LayoutDeviceIntSize GetBufferSize() override;
bool ShouldUseNativeCompositor() override;
uint32_t GetMaxUpdateRects() override;
// Does the readback for the ShouldUseNativeCompositor() case.
bool MaybeReadback(const gfx::IntSize& aReadbackSize,
const wr::ImageFormat& aReadbackFormat,
const Range<uint8_t>& aReadbackBuffer) override;
// Interface for wr::Compositor
void CompositorBeginFrame() override;
void CompositorEndFrame() override;
- void Bind(wr::NativeTileId aId, wr::DeviceIntPoint* aOffset, uint32_t* aFboId,
- wr::DeviceIntRect aDirtyRect,
- wr::DeviceIntRect aValidRect) override;
- void Unbind() override;
- bool MapTile(wr::NativeTileId aId, wr::DeviceIntRect aDirtyRect,
- wr::DeviceIntRect aValidRect, void** aData,
- int32_t* aStride) override;
- void UnmapTile() override;
void CreateSurface(wr::NativeSurfaceId aId, wr::DeviceIntPoint aVirtualOffset,
wr::DeviceIntSize aTileSize, 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 AddSurface(wr::NativeSurfaceId aId, wr::DeviceIntPoint aPosition,
wr::DeviceIntRect aClipRect) override;
CompositorCapabilities GetCompositorCapabilities() override;
@@ -77,28 +60,25 @@ class RenderCompositorOGL : public Rende
struct TileKey {
TileKey(int32_t aX, int32_t aY) : mX(aX), mY(aY) {}
int32_t mX;
int32_t mY;
};
protected:
- void InsertFrameDoneSync();
-
- void BindNativeLayer(wr::NativeTileId aId, wr::DeviceIntRect aDirtyRect,
- wr::DeviceIntRect aValidRect);
- void UnbindNativeLayer();
+ explicit RenderCompositorNative(RefPtr<widget::CompositorWidget>&& aWidget,
+ gl::GLContext* aGL = nullptr);
- bool MapNativeLayer(layers::NativeLayer* aLayer,
- const gfx::IntRect& aDirtyRect,
- const gfx::IntRect& aValidRect);
- void UnmapNativeLayer();
+ virtual bool InitDefaultFramebuffer(const gfx::IntRect& aBounds) = 0;
+ virtual void DoSwap() = 0;
+ virtual void DoFlush() {}
- RefPtr<gl::GLContext> mGL;
+ void BindNativeLayer(wr::NativeTileId aId, const gfx::IntRect& aDirtyRect);
+ void UnbindNativeLayer();
// Can be null.
RefPtr<layers::NativeLayerRoot> mNativeLayerRoot;
UniquePtr<layers::NativeLayerRootSnapshotter> mNativeLayerRootSnapshotter;
RefPtr<layers::NativeLayer> mNativeLayerForEntireWindow;
RefPtr<layers::SurfacePoolHandle> mSurfacePoolHandle;
struct TileKeyHashFn {
@@ -123,34 +103,93 @@ class RenderCompositorOGL : public Rende
struct SurfaceIdHashFn {
std::size_t operator()(const wr::NativeSurfaceId& aId) const {
return HashGeneric(wr::AsUint64(aId));
}
};
// Used in native compositor mode:
RefPtr<layers::NativeLayer> mCurrentlyBoundNativeLayer;
- RefPtr<gfx::DrawTarget> mLayerTarget;
- uint8_t* mLayerData = nullptr;
- int32_t mLayerStride = 0;
nsTArray<RefPtr<layers::NativeLayer>> mAddedLayers;
uint64_t mTotalPixelCount = 0;
uint64_t mAddedPixelCount = 0;
uint64_t mAddedClippedPixelCount = 0;
uint64_t mDrawnPixelCount = 0;
gfx::IntRect mVisibleBounds;
std::unordered_map<wr::NativeSurfaceId, Surface, SurfaceIdHashFn> mSurfaces;
TimeStamp mBeginFrameTimeStamp;
+};
+
+static inline bool operator==(const RenderCompositorNative::TileKey& a0,
+ const RenderCompositorNative::TileKey& a1) {
+ return a0.mX == a1.mX && a0.mY == a1.mY;
+}
+
+// RenderCompositorNativeOGL is a NativeLayer compositor that exposes an
+// OpenGL framebuffer for the respective NativeLayer bound to each tile.
+class RenderCompositorNativeOGL : public RenderCompositorNative {
+ public:
+ static UniquePtr<RenderCompositor> Create(
+ RefPtr<widget::CompositorWidget>&& aWidget);
+
+ RenderCompositorNativeOGL(RefPtr<widget::CompositorWidget>&& aWidget,
+ RefPtr<gl::GLContext>&& aGL);
+ virtual ~RenderCompositorNativeOGL();
+
+ bool WaitForGPU() override;
+
+ gl::GLContext* gl() const override { return mGL; }
+
+ void Bind(wr::NativeTileId aId, wr::DeviceIntPoint* aOffset, uint32_t* aFboId,
+ wr::DeviceIntRect aDirtyRect,
+ wr::DeviceIntRect aValidRect) override;
+ void Unbind() override;
+
+ protected:
+ void InsertFrameDoneSync();
+
+ bool InitDefaultFramebuffer(const gfx::IntRect& aBounds) override;
+ void DoSwap() override;
+ void DoFlush() override;
+
+ RefPtr<gl::GLContext> mGL;
// Used to apply back-pressure in WaitForGPU().
- GLsync mPreviousFrameDoneSync;
- GLsync mThisFrameDoneSync;
+ GLsync mPreviousFrameDoneSync = nullptr;
+ GLsync mThisFrameDoneSync = nullptr;
};
-static inline bool operator==(const RenderCompositorOGL::TileKey& a0,
- const RenderCompositorOGL::TileKey& a1) {
- return a0.mX == a1.mX && a0.mY == a1.mY;
-}
+// RenderCompositorNativeSWGL is a NativeLayer compositor that only
+// deals with mapping the underlying buffer for SWGL usage of a tile.
+class RenderCompositorNativeSWGL : public RenderCompositorNative {
+ public:
+ static UniquePtr<RenderCompositor> Create(
+ RefPtr<widget::CompositorWidget>&& aWidget);
+
+ RenderCompositorNativeSWGL(RefPtr<widget::CompositorWidget>&& aWidget);
+
+ void CancelFrame() override;
+
+ bool MapTile(wr::NativeTileId aId, wr::DeviceIntRect aDirtyRect,
+ wr::DeviceIntRect aValidRect, void** aData,
+ int32_t* aStride) override;
+ void UnmapTile() override;
+
+ bool GetMappedBuffer(uint8_t** aData, int32_t* aStride) override;
+
+ protected:
+ bool InitDefaultFramebuffer(const gfx::IntRect& aBounds) override;
+ void DoSwap() override;
+
+ bool MapNativeLayer(layers::NativeLayer* aLayer,
+ const gfx::IntRect& aDirtyRect,
+ const gfx::IntRect& aValidRect);
+ void UnmapNativeLayer();
+
+ RefPtr<gfx::DrawTarget> mLayerTarget;
+ uint8_t* mLayerData = nullptr;
+ int32_t mLayerStride = 0;
+};
} // namespace wr
} // namespace mozilla
#endif
--- a/gfx/webrender_bindings/RenderCompositorOGL.cpp
+++ b/gfx/webrender_bindings/RenderCompositorOGL.cpp
@@ -3,26 +3,19 @@
/* 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 "RenderCompositorOGL.h"
#include "GLContext.h"
#include "GLContextProvider.h"
-#include "mozilla/gfx/gfxVars.h"
-#include "mozilla/layers/SurfacePool.h"
-#include "mozilla/StaticPrefs_gfx.h"
#include "mozilla/webrender/RenderThread.h"
#include "mozilla/widget/CompositorWidget.h"
-#ifdef MOZ_GECKO_PROFILER
-# include "ProfilerMarkerPayload.h"
-#endif
-
namespace mozilla {
namespace wr {
/* static */
UniquePtr<RenderCompositor> RenderCompositorOGL::Create(
RefPtr<widget::CompositorWidget>&& aWidget) {
RefPtr<gl::GLContext> gl = RenderThread::Get()->SharedGL();
if (!gl) {
@@ -35,439 +28,56 @@ UniquePtr<RenderCompositor> RenderCompos
<< gfx::hexa(gl.get());
return nullptr;
}
return MakeUnique<RenderCompositorOGL>(std::move(gl), std::move(aWidget));
}
RenderCompositorOGL::RenderCompositorOGL(
RefPtr<gl::GLContext>&& aGL, RefPtr<widget::CompositorWidget>&& aWidget)
- : RenderCompositor(std::move(aWidget)),
- mGL(aGL),
- mNativeLayerRoot(GetWidget()->GetNativeLayerRoot()),
- mPreviousFrameDoneSync(nullptr),
- mThisFrameDoneSync(nullptr) {
- if (mNativeLayerRoot) {
-#ifdef XP_MACOSX
- auto pool = RenderThread::Get()->SharedSurfacePool();
- if (pool) {
- mSurfacePoolHandle = pool->GetHandleForGL(mGL);
- }
-#endif
- MOZ_RELEASE_ASSERT(mSurfacePoolHandle);
- }
+ : RenderCompositor(std::move(aWidget)), mGL(aGL) {
+ MOZ_ASSERT(mGL);
}
RenderCompositorOGL::~RenderCompositorOGL() {
- if (mNativeLayerRoot) {
- mNativeLayerRoot->SetLayers({});
- mNativeLayerForEntireWindow = nullptr;
- mNativeLayerRootSnapshotter = nullptr;
- mNativeLayerRoot = nullptr;
- }
-
- if (mGL && !mGL->MakeCurrent()) {
+ if (!mGL->MakeCurrent()) {
gfxCriticalNote
<< "Failed to make render context current during destroying.";
// Leak resources!
- mPreviousFrameDoneSync = nullptr;
- mThisFrameDoneSync = nullptr;
return;
}
-
- if (mPreviousFrameDoneSync) {
- mGL->fDeleteSync(mPreviousFrameDoneSync);
- }
- if (mThisFrameDoneSync) {
- mGL->fDeleteSync(mThisFrameDoneSync);
- }
}
bool RenderCompositorOGL::BeginFrame() {
- if (mGL && !mGL->MakeCurrent()) {
+ if (!mGL->MakeCurrent()) {
gfxCriticalNote << "Failed to make render context current, can't draw.";
return false;
}
- gfx::IntSize bufferSize = GetBufferSize().ToUnknownSize();
- if (mNativeLayerRoot && !ShouldUseNativeCompositor()) {
- if (mNativeLayerForEntireWindow &&
- mNativeLayerForEntireWindow->GetSize() != bufferSize) {
- mNativeLayerRoot->RemoveLayer(mNativeLayerForEntireWindow);
- mNativeLayerForEntireWindow = nullptr;
- }
- if (!mNativeLayerForEntireWindow) {
- mNativeLayerForEntireWindow =
- mNativeLayerRoot->CreateLayer(bufferSize, false, mSurfacePoolHandle);
- mNativeLayerForEntireWindow->SetSurfaceIsFlipped(true);
- mNativeLayerRoot->AppendLayer(mNativeLayerForEntireWindow);
- }
- }
- if (mNativeLayerForEntireWindow) {
- gfx::IntRect bounds({}, bufferSize);
- if (mGL) {
- Maybe<GLuint> fbo = mNativeLayerForEntireWindow->NextSurfaceAsFramebuffer(
- bounds, bounds, true);
- if (!fbo) {
- return false;
- }
- mGL->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, *fbo);
- } else if (!MapNativeLayer(mNativeLayerForEntireWindow, bounds, bounds)) {
- return false;
- }
- } else if (mGL) {
- mGL->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, mGL->GetDefaultFramebuffer());
- }
-
+ mGL->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, mGL->GetDefaultFramebuffer());
return true;
}
-void RenderCompositorOGL::CancelFrame() {
- if (mNativeLayerForEntireWindow && mLayerTarget) {
- UnmapNativeLayer();
- }
-}
-
RenderedFrameId RenderCompositorOGL::EndFrame(
const nsTArray<DeviceIntRect>& aDirtyRects) {
RenderedFrameId frameId = GetNextRenderFrameId();
-
- if (mGL) {
- InsertFrameDoneSync();
- if (!mNativeLayerRoot) {
- mGL->SwapBuffers();
- } else if (mNativeLayerForEntireWindow) {
- mGL->fFlush();
- }
- } else if (mNativeLayerForEntireWindow && mLayerTarget) {
- UnmapNativeLayer();
- }
-
- if (mNativeLayerForEntireWindow) {
- mNativeLayerForEntireWindow->NotifySurfaceReady();
- mNativeLayerRoot->CommitToScreen();
- }
-
+ mGL->SwapBuffers();
return frameId;
}
-void RenderCompositorOGL::InsertFrameDoneSync() {
-#ifdef XP_MACOSX
- // Only do this on macOS.
- // On other platforms, SwapBuffers automatically applies back-pressure.
- if (mThisFrameDoneSync) {
- mGL->fDeleteSync(mThisFrameDoneSync);
- }
- mThisFrameDoneSync = mGL->fFenceSync(LOCAL_GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
-#endif
-}
-
-bool RenderCompositorOGL::WaitForGPU() {
- if (mPreviousFrameDoneSync) {
- AUTO_PROFILER_LABEL("Waiting for GPU to finish previous frame", GRAPHICS);
- mGL->fClientWaitSync(mPreviousFrameDoneSync,
- LOCAL_GL_SYNC_FLUSH_COMMANDS_BIT,
- LOCAL_GL_TIMEOUT_IGNORED);
- mGL->fDeleteSync(mPreviousFrameDoneSync);
- }
- mPreviousFrameDoneSync = mThisFrameDoneSync;
- mThisFrameDoneSync = nullptr;
-
- return true;
-}
-
void RenderCompositorOGL::Pause() {}
bool RenderCompositorOGL::Resume() { return true; }
LayoutDeviceIntSize RenderCompositorOGL::GetBufferSize() {
return mWidget->GetClientSize();
}
-bool RenderCompositorOGL::ShouldUseNativeCompositor() {
- return mNativeLayerRoot && gfx::gfxVars::UseWebRenderCompositor();
-}
-
-bool RenderCompositorOGL::MaybeReadback(const gfx::IntSize& aReadbackSize,
- const wr::ImageFormat& aReadbackFormat,
- const Range<uint8_t>& aReadbackBuffer) {
- if (!ShouldUseNativeCompositor()) {
- return false;
- }
-
- MOZ_RELEASE_ASSERT(aReadbackFormat == wr::ImageFormat::BGRA8);
- if (!mNativeLayerRootSnapshotter) {
- mNativeLayerRootSnapshotter = mNativeLayerRoot->CreateSnapshotter();
- }
- bool success = mNativeLayerRootSnapshotter->ReadbackPixels(
- aReadbackSize, gfx::SurfaceFormat::B8G8R8A8, aReadbackBuffer);
-
- // ReadbackPixels might have changed the current context. Make sure mGL is
- // current again.
- if (mGL) {
- mGL->MakeCurrent();
- }
-
- return success;
-}
-
-uint32_t RenderCompositorOGL::GetMaxUpdateRects() {
- if (ShouldUseNativeCompositor() &&
- StaticPrefs::gfx_webrender_compositor_max_update_rects_AtStartup() > 0) {
- return 1;
- }
- return 0;
-}
-
-void RenderCompositorOGL::CompositorBeginFrame() {
- mAddedLayers.Clear();
- mAddedPixelCount = 0;
- mAddedClippedPixelCount = 0;
- mBeginFrameTimeStamp = TimeStamp::NowUnfuzzed();
- mSurfacePoolHandle->OnBeginFrame();
-}
-
-void RenderCompositorOGL::CompositorEndFrame() {
-#ifdef MOZ_GECKO_PROFILER
- if (profiler_thread_is_being_profiled()) {
- auto bufferSize = GetBufferSize();
- uint64_t windowPixelCount = uint64_t(bufferSize.width) * bufferSize.height;
- int nativeLayerCount = 0;
- for (const auto& it : mSurfaces) {
- nativeLayerCount += int(it.second.mNativeLayers.size());
- }
- profiler_add_text_marker(
- "WR OS Compositor frame",
- nsPrintfCString("%d%% painting, %d%% overdraw, %d used "
- "layers (%d%% memory) + %d unused layers (%d%% memory)",
- int(mDrawnPixelCount * 100 / windowPixelCount),
- int(mAddedClippedPixelCount * 100 / windowPixelCount),
- int(mAddedLayers.Length()),
- int(mAddedPixelCount * 100 / windowPixelCount),
- int(nativeLayerCount - mAddedLayers.Length()),
- int((mTotalPixelCount - mAddedPixelCount) * 100 /
- windowPixelCount)),
- JS::ProfilingCategoryPair::GRAPHICS, mBeginFrameTimeStamp,
- TimeStamp::NowUnfuzzed());
- }
-#endif
- mDrawnPixelCount = 0;
-
- if (mGL) {
- mGL->fFlush();
- }
-
- mNativeLayerRoot->SetLayers(mAddedLayers);
- mNativeLayerRoot->CommitToScreen();
- mSurfacePoolHandle->OnEndFrame();
-}
-
-void RenderCompositorOGL::BindNativeLayer(wr::NativeTileId aId,
- wr::DeviceIntRect aDirtyRect,
- wr::DeviceIntRect aValidRect) {
- MOZ_RELEASE_ASSERT(!mCurrentlyBoundNativeLayer);
-
- auto surfaceCursor = mSurfaces.find(aId.surface_id);
- MOZ_RELEASE_ASSERT(surfaceCursor != mSurfaces.end());
- Surface& surface = surfaceCursor->second;
-
- auto layerCursor = surface.mNativeLayers.find(TileKey(aId.x, aId.y));
- MOZ_RELEASE_ASSERT(layerCursor != surface.mNativeLayers.end());
- RefPtr<layers::NativeLayer> layer = layerCursor->second;
-
- gfx::IntRect dirtyRect(aDirtyRect.origin.x, aDirtyRect.origin.y,
- aDirtyRect.size.width, aDirtyRect.size.height);
-
- mCurrentlyBoundNativeLayer = layer;
-
- mDrawnPixelCount += dirtyRect.Area();
-}
-
-void RenderCompositorOGL::UnbindNativeLayer() {
- MOZ_RELEASE_ASSERT(mCurrentlyBoundNativeLayer);
-
- mCurrentlyBoundNativeLayer->NotifySurfaceReady();
- mCurrentlyBoundNativeLayer = nullptr;
-}
-
-void RenderCompositorOGL::Bind(wr::NativeTileId aId,
- wr::DeviceIntPoint* aOffset, uint32_t* aFboId,
- wr::DeviceIntRect aDirtyRect,
- wr::DeviceIntRect aValidRect) {
- BindNativeLayer(aId, aDirtyRect, aValidRect);
-
- gfx::IntRect validRect(aValidRect.origin.x, aValidRect.origin.y,
- aValidRect.size.width, aValidRect.size.height);
- gfx::IntRect dirtyRect(aDirtyRect.origin.x, aDirtyRect.origin.y,
- aDirtyRect.size.width, aDirtyRect.size.height);
-
- Maybe<GLuint> fbo = mCurrentlyBoundNativeLayer->NextSurfaceAsFramebuffer(
- validRect, dirtyRect, true);
- MOZ_RELEASE_ASSERT(fbo); // TODO: make fallible
-
- *aFboId = *fbo;
- *aOffset = wr::DeviceIntPoint{0, 0};
-}
-
-void RenderCompositorOGL::Unbind() {
- mGL->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, 0);
-
- UnbindNativeLayer();
-}
-
-bool RenderCompositorOGL::MapNativeLayer(layers::NativeLayer* aLayer,
- const gfx::IntRect& aDirtyRect,
- const gfx::IntRect& aValidRect) {
- uint8_t* data = nullptr;
- gfx::IntSize size;
- int32_t stride = 0;
- gfx::SurfaceFormat format = gfx::SurfaceFormat::UNKNOWN;
- RefPtr<gfx::DrawTarget> dt = aLayer->NextSurfaceAsDrawTarget(
- aValidRect, gfx::IntRegion(aDirtyRect), gfx::BackendType::SKIA);
- if (!dt || !dt->LockBits(&data, &size, &stride, &format)) {
- return false;
- }
- MOZ_ASSERT(format == gfx::SurfaceFormat::B8G8R8A8 ||
- format == gfx::SurfaceFormat::B8G8R8X8);
- mLayerTarget = std::move(dt);
- mLayerData = data;
- mLayerStride = stride;
- return true;
-}
-
-void RenderCompositorOGL::UnmapNativeLayer() {
- MOZ_ASSERT(mLayerTarget && mLayerData);
- mLayerTarget->ReleaseBits(mLayerData);
- mLayerTarget = nullptr;
- mLayerData = nullptr;
- mLayerStride = 0;
-}
-
-bool RenderCompositorOGL::GetMappedBuffer(uint8_t** aData, int32_t* aStride) {
- if (mNativeLayerForEntireWindow && mLayerData) {
- *aData = mLayerData;
- *aStride = mLayerStride;
- return true;
- }
- return false;
-}
-
-bool RenderCompositorOGL::MapTile(wr::NativeTileId aId,
- wr::DeviceIntRect aDirtyRect,
- wr::DeviceIntRect aValidRect,
- void** aData, int32_t* aStride) {
- if (!mNativeLayerRoot || mNativeLayerForEntireWindow) {
- return false;
- }
- BindNativeLayer(aId, aDirtyRect, aValidRect);
- gfx::IntRect dirtyRect(aDirtyRect.origin.x, aDirtyRect.origin.y,
- aDirtyRect.size.width, aDirtyRect.size.height);
- gfx::IntRect validRect(aValidRect.origin.x, aValidRect.origin.y,
- aValidRect.size.width, aValidRect.size.height);
- if (!MapNativeLayer(mCurrentlyBoundNativeLayer, dirtyRect, validRect)) {
- UnbindNativeLayer();
- return false;
- }
- *aData = mLayerData;
- *aStride = mLayerStride;
- return true;
-}
-
-void RenderCompositorOGL::UnmapTile() {
- if (!mNativeLayerForEntireWindow && mCurrentlyBoundNativeLayer) {
- UnmapNativeLayer();
- UnbindNativeLayer();
- }
-}
-
-void RenderCompositorOGL::CreateSurface(wr::NativeSurfaceId aId,
- wr::DeviceIntPoint aVirtualOffset,
- wr::DeviceIntSize aTileSize,
- bool aIsOpaque) {
- MOZ_RELEASE_ASSERT(mSurfaces.find(aId) == mSurfaces.end());
- mSurfaces.insert({aId, Surface{aTileSize, aIsOpaque}});
-}
-
-void RenderCompositorOGL::DestroySurface(NativeSurfaceId aId) {
- auto surfaceCursor = mSurfaces.find(aId);
- MOZ_RELEASE_ASSERT(surfaceCursor != mSurfaces.end());
-
- Surface& surface = surfaceCursor->second;
- for (const auto& iter : surface.mNativeLayers) {
- mTotalPixelCount -= gfx::IntRect({}, iter.second->GetSize()).Area();
- }
-
- mSurfaces.erase(surfaceCursor);
-}
-
-void RenderCompositorOGL::CreateTile(wr::NativeSurfaceId aId, int aX, int aY) {
- auto surfaceCursor = mSurfaces.find(aId);
- MOZ_RELEASE_ASSERT(surfaceCursor != mSurfaces.end());
- Surface& surface = surfaceCursor->second;
-
- RefPtr<layers::NativeLayer> layer = mNativeLayerRoot->CreateLayer(
- surface.TileSize(), surface.mIsOpaque, mSurfacePoolHandle);
- surface.mNativeLayers.insert({TileKey(aX, aY), layer});
- mTotalPixelCount += gfx::IntRect({}, layer->GetSize()).Area();
-}
-
-void RenderCompositorOGL::DestroyTile(wr::NativeSurfaceId aId, int aX, int aY) {
- auto surfaceCursor = mSurfaces.find(aId);
- MOZ_RELEASE_ASSERT(surfaceCursor != mSurfaces.end());
- Surface& surface = surfaceCursor->second;
-
- auto layerCursor = surface.mNativeLayers.find(TileKey(aX, aY));
- MOZ_RELEASE_ASSERT(layerCursor != surface.mNativeLayers.end());
- RefPtr<layers::NativeLayer> layer = std::move(layerCursor->second);
- surface.mNativeLayers.erase(layerCursor);
- mTotalPixelCount -= gfx::IntRect({}, layer->GetSize()).Area();
-
- // If the layer is currently present in mNativeLayerRoot, it will be destroyed
- // once CompositorEndFrame() replaces mNativeLayerRoot's layers and drops that
- // reference. So until that happens, the layer still needs to hold on to its
- // front buffer. However, we can tell it to drop its back buffers now, because
- // we know that we will never draw to it again.
- // Dropping the back buffers now puts them back in the surface pool, so those
- // surfaces can be immediately re-used for drawing in other layers in the
- // current frame.
- layer->DiscardBackbuffers();
-}
-
-void RenderCompositorOGL::AddSurface(wr::NativeSurfaceId aId,
- wr::DeviceIntPoint aPosition,
- wr::DeviceIntRect aClipRect) {
- MOZ_RELEASE_ASSERT(!mCurrentlyBoundNativeLayer);
-
- auto surfaceCursor = mSurfaces.find(aId);
- MOZ_RELEASE_ASSERT(surfaceCursor != mSurfaces.end());
- const Surface& surface = surfaceCursor->second;
-
- for (auto it = surface.mNativeLayers.begin();
- it != surface.mNativeLayers.end(); ++it) {
- RefPtr<layers::NativeLayer> layer = it->second;
- gfx::IntSize layerSize = layer->GetSize();
- gfx::IntPoint layerPosition(
- aPosition.x + surface.mTileSize.width * it->first.mX,
- aPosition.y + surface.mTileSize.height * it->first.mY);
- layer->SetPosition(layerPosition);
- gfx::IntRect clipRect(aClipRect.origin.x, aClipRect.origin.y,
- aClipRect.size.width, aClipRect.size.height);
- layer->SetClipRect(Some(clipRect));
- mAddedLayers.AppendElement(layer);
-
- mAddedPixelCount += layerSize.width * layerSize.height;
- gfx::IntRect visibleRect =
- clipRect.Intersect(layer->CurrentSurfaceDisplayRect() + layerPosition);
- mAddedClippedPixelCount += visibleRect.Area();
- }
-}
-
CompositorCapabilities RenderCompositorOGL::GetCompositorCapabilities() {
CompositorCapabilities caps;
- // CoreAnimation doesn't use virtual surfaces
caps.virtual_surface_size = 0;
return caps;
}
} // namespace wr
} // namespace mozilla
--- a/gfx/webrender_bindings/RenderCompositorOGL.h
+++ b/gfx/webrender_bindings/RenderCompositorOGL.h
@@ -4,153 +4,41 @@
* 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_OGL_H
#define MOZILLA_GFX_RENDERCOMPOSITOR_OGL_H
#include "GLTypes.h"
#include "mozilla/webrender/RenderCompositor.h"
-#include "mozilla/TimeStamp.h"
namespace mozilla {
-
-namespace layers {
-class NativeLayerRootSnapshotter;
-class NativeLayerRoot;
-class NativeLayer;
-class SurfacePoolHandle;
-} // namespace layers
-
namespace wr {
class RenderCompositorOGL : public RenderCompositor {
public:
static UniquePtr<RenderCompositor> Create(
RefPtr<widget::CompositorWidget>&& aWidget);
RenderCompositorOGL(RefPtr<gl::GLContext>&& aGL,
RefPtr<widget::CompositorWidget>&& aWidget);
virtual ~RenderCompositorOGL();
bool BeginFrame() override;
- void CancelFrame() override;
RenderedFrameId EndFrame(const nsTArray<DeviceIntRect>& aDirtyRects) final;
- bool WaitForGPU() override;
void Pause() override;
bool Resume() override;
- bool GetMappedBuffer(uint8_t** aData, int32_t* aStride) override;
-
gl::GLContext* gl() const override { return mGL; }
- bool UseANGLE() const override { return false; }
-
LayoutDeviceIntSize GetBufferSize() override;
- bool ShouldUseNativeCompositor() override;
- uint32_t GetMaxUpdateRects() override;
-
- // Does the readback for the ShouldUseNativeCompositor() case.
- bool MaybeReadback(const gfx::IntSize& aReadbackSize,
- const wr::ImageFormat& aReadbackFormat,
- const Range<uint8_t>& aReadbackBuffer) override;
-
// Interface for wr::Compositor
- void CompositorBeginFrame() override;
- void CompositorEndFrame() override;
- void Bind(wr::NativeTileId aId, wr::DeviceIntPoint* aOffset, uint32_t* aFboId,
- wr::DeviceIntRect aDirtyRect,
- wr::DeviceIntRect aValidRect) override;
- void Unbind() override;
- bool MapTile(wr::NativeTileId aId, wr::DeviceIntRect aDirtyRect,
- wr::DeviceIntRect aValidRect, void** aData,
- int32_t* aStride) override;
- void UnmapTile() override;
- void CreateSurface(wr::NativeSurfaceId aId, wr::DeviceIntPoint aVirtualOffset,
- wr::DeviceIntSize aTileSize, 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 AddSurface(wr::NativeSurfaceId aId, wr::DeviceIntPoint aPosition,
- wr::DeviceIntRect aClipRect) override;
CompositorCapabilities GetCompositorCapabilities() override;
- struct TileKey {
- TileKey(int32_t aX, int32_t aY) : mX(aX), mY(aY) {}
-
- int32_t mX;
- int32_t mY;
- };
-
protected:
- void InsertFrameDoneSync();
-
- void BindNativeLayer(wr::NativeTileId aId, wr::DeviceIntRect aDirtyRect,
- wr::DeviceIntRect aValidRect);
- void UnbindNativeLayer();
-
- bool MapNativeLayer(layers::NativeLayer* aLayer,
- const gfx::IntRect& aDirtyRect,
- const gfx::IntRect& aValidRect);
- void UnmapNativeLayer();
-
RefPtr<gl::GLContext> mGL;
-
- // Can be null.
- RefPtr<layers::NativeLayerRoot> mNativeLayerRoot;
- UniquePtr<layers::NativeLayerRootSnapshotter> mNativeLayerRootSnapshotter;
- RefPtr<layers::NativeLayer> mNativeLayerForEntireWindow;
- RefPtr<layers::SurfacePoolHandle> mSurfacePoolHandle;
-
- struct TileKeyHashFn {
- std::size_t operator()(const TileKey& aId) const {
- return HashGeneric(aId.mX, aId.mY);
- }
- };
-
- struct Surface {
- explicit Surface(wr::DeviceIntSize aTileSize, bool aIsOpaque)
- : mTileSize(aTileSize), mIsOpaque(aIsOpaque) {}
- gfx::IntSize TileSize() {
- return gfx::IntSize(mTileSize.width, mTileSize.height);
- }
-
- wr::DeviceIntSize mTileSize;
- bool mIsOpaque;
- std::unordered_map<TileKey, RefPtr<layers::NativeLayer>, TileKeyHashFn>
- mNativeLayers;
- };
-
- struct SurfaceIdHashFn {
- std::size_t operator()(const wr::NativeSurfaceId& aId) const {
- return HashGeneric(wr::AsUint64(aId));
- }
- };
-
- // Used in native compositor mode:
- RefPtr<layers::NativeLayer> mCurrentlyBoundNativeLayer;
- RefPtr<gfx::DrawTarget> mLayerTarget;
- uint8_t* mLayerData = nullptr;
- int32_t mLayerStride = 0;
- nsTArray<RefPtr<layers::NativeLayer>> mAddedLayers;
- uint64_t mTotalPixelCount = 0;
- uint64_t mAddedPixelCount = 0;
- uint64_t mAddedClippedPixelCount = 0;
- uint64_t mDrawnPixelCount = 0;
- gfx::IntRect mVisibleBounds;
- std::unordered_map<wr::NativeSurfaceId, Surface, SurfaceIdHashFn> mSurfaces;
- TimeStamp mBeginFrameTimeStamp;
-
- // Used to apply back-pressure in WaitForGPU().
- GLsync mPreviousFrameDoneSync;
- GLsync mThisFrameDoneSync;
};
-static inline bool operator==(const RenderCompositorOGL::TileKey& a0,
- const RenderCompositorOGL::TileKey& a1) {
- return a0.mX == a1.mX && a0.mY == a1.mY;
-}
-
} // namespace wr
} // namespace mozilla
#endif
--- a/gfx/webrender_bindings/moz.build
+++ b/gfx/webrender_bindings/moz.build
@@ -40,19 +40,21 @@ UNIFIED_SOURCES += [
'RenderTextureHostWrapper.cpp',
'RenderThread.cpp',
'WebRenderAPI.cpp',
'WebRenderTypes.cpp',
]
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
EXPORTS.mozilla.webrender += [
+ 'RenderCompositorNative.h',
'RenderMacIOSurfaceTextureHostOGL.h',
]
UNIFIED_SOURCES += [
+ 'RenderCompositorNative.cpp',
'RenderMacIOSurfaceTextureHostOGL.cpp',
]
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
EXPORTS.mozilla.webrender += [
'RenderAndroidSurfaceTextureHostOGL.h',
'RenderCompositorEGL.h',
]