зеркало из https://github.com/mozilla/gecko-dev.git
b=1015218 Buffer image content layers on server-side xlib surfaces with OMTC basic r=karlt
With image offscreen surfaces enabled for content layers on GTK3, our Basic compositor needs a way to deal with image layers buffering and compositing in a performant way. This patch subclasses BasicCompositor into a new X11BasicCompositor and makes use of a new TextureSource (X11DataTextureSourceBasic) in order to buffer TextureHost's data into gfxXlibSurface on compositor side so that we can use XRender when available to composite layer contents directly to the Window. When this buffering will occur, switch to ContentClientSingleBuffered. --HG-- extra : rebase_source : adad6b1c05dcf516a1ea84c6a529df5f141c198f
This commit is contained in:
Родитель
ab4ba2bd41
Коммит
ebac609549
|
@ -0,0 +1,129 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* 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 "X11BasicCompositor.h"
|
||||
#include "gfxPlatform.h"
|
||||
#include "gfx2DGlue.h"
|
||||
#include "gfxXlibSurface.h"
|
||||
#include "gfxImageSurface.h"
|
||||
#include "mozilla/X11Util.h"
|
||||
|
||||
namespace mozilla {
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
namespace layers {
|
||||
|
||||
bool
|
||||
X11DataTextureSourceBasic::Update(gfx::DataSourceSurface* aSurface,
|
||||
nsIntRegion* aDestRegion,
|
||||
gfx::IntPoint* aSrcOffset)
|
||||
{
|
||||
// Reallocate our internal X11 surface if we don't have a DrawTarget yet,
|
||||
// or if we changed surface size or format since last update.
|
||||
if (!mBufferDrawTarget ||
|
||||
(aSurface->GetSize() != mBufferDrawTarget->GetSize()) ||
|
||||
(aSurface->GetFormat() != mBufferDrawTarget->GetFormat())) {
|
||||
|
||||
nsRefPtr<gfxASurface> surf;
|
||||
gfxImageFormat imageFormat = SurfaceFormatToImageFormat(aSurface->GetFormat());
|
||||
Display *display = DefaultXDisplay();
|
||||
Screen *screen = DefaultScreenOfDisplay(display);
|
||||
XRenderPictFormat *xrenderFormat =
|
||||
gfxXlibSurface::FindRenderFormat(display, imageFormat);
|
||||
|
||||
if (xrenderFormat) {
|
||||
surf = gfxXlibSurface::Create(screen, xrenderFormat,
|
||||
ThebesIntSize(aSurface->GetSize()));
|
||||
}
|
||||
|
||||
if (!surf) {
|
||||
NS_WARNING("Couldn't create native surface, fallback to image surface");
|
||||
surf = new gfxImageSurface(ThebesIntSize(aSurface->GetSize()), imageFormat);
|
||||
}
|
||||
|
||||
mBufferDrawTarget = gfxPlatform::GetPlatform()->
|
||||
CreateDrawTargetForSurface(surf, aSurface->GetSize());
|
||||
}
|
||||
|
||||
// Image contents have changed, upload to our DrawTarget
|
||||
// If aDestRegion is null, means we're updating the whole surface
|
||||
// Note : Incremental update with a source offset is only used on Mac.
|
||||
NS_ASSERTION(!aSrcOffset, "SrcOffset should not be used with linux OMTC basic");
|
||||
|
||||
if (aDestRegion) {
|
||||
nsIntRegionRectIterator iter(*aDestRegion);
|
||||
while (const nsIntRect* iterRect = iter.Next()) {
|
||||
IntRect srcRect(iterRect->x, iterRect->y, iterRect->width, iterRect->height);
|
||||
IntPoint dstPoint(iterRect->x, iterRect->y);
|
||||
|
||||
// We're uploading regions to our buffer, so let's just copy contents over
|
||||
mBufferDrawTarget->CopySurface(aSurface, srcRect, dstPoint);
|
||||
}
|
||||
} else {
|
||||
// We're uploading the whole buffer, so let's just copy the full surface
|
||||
IntSize size = aSurface->GetSize();
|
||||
mBufferDrawTarget->CopySurface(aSurface, IntRect(0, 0, size.width, size.height),
|
||||
IntPoint(0, 0));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
TextureSourceBasic*
|
||||
X11DataTextureSourceBasic::AsSourceBasic()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
IntSize
|
||||
X11DataTextureSourceBasic::GetSize() const
|
||||
{
|
||||
if (!mBufferDrawTarget) {
|
||||
NS_WARNING("Trying to query the size of an uninitialized TextureSource");
|
||||
return IntSize(0, 0);
|
||||
} else {
|
||||
return mBufferDrawTarget->GetSize();
|
||||
}
|
||||
}
|
||||
|
||||
gfx::SurfaceFormat
|
||||
X11DataTextureSourceBasic::GetFormat() const
|
||||
{
|
||||
if (!mBufferDrawTarget) {
|
||||
NS_WARNING("Trying to query the format of an uninitialized TextureSource");
|
||||
return gfx::SurfaceFormat::UNKNOWN;
|
||||
} else {
|
||||
return mBufferDrawTarget->GetFormat();
|
||||
}
|
||||
}
|
||||
|
||||
SourceSurface*
|
||||
X11DataTextureSourceBasic::GetSurface(DrawTarget* aTarget)
|
||||
{
|
||||
RefPtr<gfx::SourceSurface> surface;
|
||||
if (mBufferDrawTarget) {
|
||||
surface = mBufferDrawTarget->Snapshot();
|
||||
return surface.get();
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
X11DataTextureSourceBasic::DeallocateDeviceData()
|
||||
{
|
||||
mBufferDrawTarget = nullptr;
|
||||
}
|
||||
|
||||
TemporaryRef<DataTextureSource>
|
||||
X11BasicCompositor::CreateDataTextureSource(TextureFlags aFlags)
|
||||
{
|
||||
RefPtr<DataTextureSource> result =
|
||||
new X11DataTextureSourceBasic();
|
||||
return result.forget();
|
||||
}
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
|
@ -0,0 +1,57 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* 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_X11BASICCOMPOSITOR_H
|
||||
#define MOZILLA_GFX_X11BASICCOMPOSITOR_H
|
||||
|
||||
#include "mozilla/layers/BasicCompositor.h"
|
||||
#include "mozilla/layers/X11TextureSourceBasic.h"
|
||||
#include "mozilla/layers/TextureHostBasic.h"
|
||||
#include "gfxXlibSurface.h"
|
||||
#include "mozilla/gfx/2D.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
// TextureSource for Image-backed surfaces.
|
||||
class X11DataTextureSourceBasic : public DataTextureSource
|
||||
, public TextureSourceBasic
|
||||
{
|
||||
public:
|
||||
X11DataTextureSourceBasic() {};
|
||||
|
||||
virtual bool Update(gfx::DataSourceSurface* aSurface,
|
||||
nsIntRegion* aDestRegion = nullptr,
|
||||
gfx::IntPoint* aSrcOffset = nullptr) MOZ_OVERRIDE;
|
||||
|
||||
virtual TextureSourceBasic* AsSourceBasic() MOZ_OVERRIDE;
|
||||
|
||||
virtual gfx::SourceSurface* GetSurface(gfx::DrawTarget* aTarget) MOZ_OVERRIDE;
|
||||
|
||||
virtual void DeallocateDeviceData() MOZ_OVERRIDE;
|
||||
|
||||
virtual gfx::IntSize GetSize() const MOZ_OVERRIDE;
|
||||
|
||||
virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE;
|
||||
|
||||
private:
|
||||
// We are going to buffer layer content on this xlib draw target
|
||||
RefPtr<mozilla::gfx::DrawTarget> mBufferDrawTarget;
|
||||
};
|
||||
|
||||
class X11BasicCompositor : public BasicCompositor
|
||||
{
|
||||
public:
|
||||
|
||||
X11BasicCompositor(nsIWidget *aWidget) : BasicCompositor(aWidget) {}
|
||||
|
||||
virtual TemporaryRef<DataTextureSource>
|
||||
CreateDataTextureSource(TextureFlags aFlags = TextureFlags::NO_FLAGS) MOZ_OVERRIDE;
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
||||
#endif /* MOZILLA_GFX_X11BASICCOMPOSITOR_H */
|
|
@ -32,6 +32,9 @@
|
|||
#ifdef XP_WIN
|
||||
#include "gfxWindowsPlatform.h"
|
||||
#endif
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
#include "gfxPlatformGtk.h"
|
||||
#endif
|
||||
#include "gfx2DGlue.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
@ -72,6 +75,13 @@ ContentClient::CreateContentClient(CompositableForwarder* aForwarder)
|
|||
if (backend == LayersBackend::LAYERS_D3D11) {
|
||||
useDoubleBuffering = !!gfxWindowsPlatform::GetPlatform()->GetD2DDevice();
|
||||
} else
|
||||
#endif
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
// We can't use double buffering when using image content with
|
||||
// Xrender support on Linux, as ContentHostDoubleBuffered is not
|
||||
// suited for direct uploads to the server.
|
||||
if (!gfxPlatformGtk::GetPlatform()->UseImageOffscreenSurfaces() ||
|
||||
!gfxPlatformGtk::GetPlatform()->UseXRender())
|
||||
#endif
|
||||
{
|
||||
useDoubleBuffering = (LayerManagerComposite::SupportsDirectTexturing() &&
|
||||
|
|
|
@ -19,6 +19,9 @@
|
|||
#include "base/tracked.h" // for FROM_HERE
|
||||
#include "gfxContext.h" // for gfxContext
|
||||
#include "gfxPlatform.h" // for gfxPlatform
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
#include "gfxPlatformGtk.h" // for gfxPlatform
|
||||
#endif
|
||||
#include "gfxPrefs.h" // for gfxPrefs
|
||||
#include "ipc/ShadowLayersManager.h" // for ShadowLayersManager
|
||||
#include "mozilla/AutoRestore.h" // for AutoRestore
|
||||
|
@ -36,6 +39,9 @@
|
|||
#include "mozilla/layers/LayersTypes.h"
|
||||
#include "mozilla/layers/PLayerTransactionParent.h"
|
||||
#include "mozilla/mozalloc.h" // for operator new, etc
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
#include "basic/X11BasicCompositor.h" // for X11BasicCompositor
|
||||
#endif
|
||||
#include "nsCOMPtr.h" // for already_AddRefed
|
||||
#include "nsDebug.h" // for NS_ABORT_IF_FALSE, etc
|
||||
#include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc
|
||||
|
@ -898,7 +904,14 @@ CompositorParent::InitializeLayerManager(const nsTArray<LayersBackend>& aBackend
|
|||
mEGLSurfaceSize.height,
|
||||
mUseExternalSurfaceSize);
|
||||
} else if (aBackendHints[i] == LayersBackend::LAYERS_BASIC) {
|
||||
compositor = new BasicCompositor(mWidget);
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
if (gfxPlatformGtk::GetPlatform()->UseXRender()) {
|
||||
compositor = new X11BasicCompositor(mWidget);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
compositor = new BasicCompositor(mWidget);
|
||||
}
|
||||
#ifdef XP_WIN
|
||||
} else if (aBackendHints[i] == LayersBackend::LAYERS_D3D11) {
|
||||
compositor = new CompositorD3D11(mWidget);
|
||||
|
|
|
@ -182,6 +182,7 @@ if CONFIG['MOZ_X11']:
|
|||
]
|
||||
SOURCES += [
|
||||
'basic/TextureClientX11.cpp',
|
||||
'basic/X11BasicCompositor.cpp',
|
||||
'basic/X11TextureSourceBasic.cpp',
|
||||
'composite/X11TextureHost.cpp',
|
||||
'ipc/ShadowLayerUtilsX11.cpp',
|
||||
|
|
Загрузка…
Ссылка в новой задаче