Bug 1464032 Part 6: Add remote canvas pref and refactor TextuteData creation to use it. r=mattwoodrow

This is ground work for when we will be returning a recording TextureData for
certain types in subsequent patches.
This commit is contained in:
Bob Owen 2018-11-28 20:44:27 +00:00
Родитель 049e2169cc
Коммит e25e5074c1
12 изменённых файлов: 221 добавлений и 80 удалений

Просмотреть файл

@ -1407,15 +1407,6 @@ bool CanvasRenderingContext2D::TrySharedTarget(
return false;
}
#ifdef XP_WIN
// Bug 1285271 - Disable shared buffer provider on Windows with D2D due to
// instability
if (gfxPlatform::GetPlatform()->GetPreferredCanvasBackend() ==
BackendType::DIRECT2D1_1) {
return false;
}
#endif
RefPtr<LayerManager> layerManager =
LayerManagerFromCanvasElement(mCanvasElement);

Просмотреть файл

@ -50,7 +50,8 @@ class gfxVarReceiver;
_(UseOMTP, bool, false) \
_(AllowD3D11KeyedMutex, bool, false) \
_(SystemTextQuality, int32_t, 5 /* CLEARTYPE_QUALITY */) \
_(LayersWindowRecordingPath, nsCString, nsCString())
_(LayersWindowRecordingPath, nsCString, nsCString()) \
_(RemoteCanvasEnabled, bool, false) \
/* Add new entries above this line. */

Просмотреть файл

@ -155,6 +155,16 @@ enum class LayersBackend : int8_t {
LAYERS_LAST
};
enum class TextureType : int8_t {
Unknown = 0,
D3D11,
DIB,
X11,
MacIOSurface,
AndroidNativeWindow,
Last
};
enum class BufferMode : int8_t { BUFFER_NONE, BUFFERED };
enum class DrawRegionClip : int8_t { DRAW, NONE };

Просмотреть файл

@ -10,6 +10,7 @@
#include "mozilla/layers/ShadowLayers.h"
#include "mozilla/layers/TextureClient.h"
#include "mozilla/gfx/Logging.h"
#include "mozilla/StaticPrefs.h"
#include "pratom.h"
#include "gfxPlatform.h"
@ -103,6 +104,21 @@ PersistentBufferProviderShared::Create(gfx::IntSize aSize,
return nullptr;
}
if (!StaticPrefs::PersistentBufferProviderSharedEnabled()) {
return nullptr;
}
#ifdef XP_WIN
// Bug 1285271 - Disable shared buffer provider on Windows with D2D due to
// instability, unless we are remoting the canvas drawing to the GPU process.
if (gfxPlatform::GetPlatform()->GetPreferredCanvasBackend() ==
BackendType::DIRECT2D1_1 &&
!TextureData::IsRemote(aKnowsCompositor->GetCompositorBackendType(),
BackendSelector::Canvas)) {
return nullptr;
}
#endif
RefPtr<TextureClient> texture = TextureClient::CreateForDrawing(
aKnowsCompositor, aFormat, aSize, BackendSelector::Canvas,
TextureFlags::DEFAULT | TextureFlags::NON_BLOCKING_READ_LOCK,

Просмотреть файл

@ -862,8 +862,7 @@ ClientLayerManager::CreatePersistentBufferProvider(const gfx::IntSize& aSize,
// because the canvas will most likely be flattened into a thebes layer
// instead of being sent to the compositor, in which case rendering into
// shared memory is wasteful.
if (IsCompositingCheap() &&
StaticPrefs::PersistentBufferProviderSharedEnabled()) {
if (IsCompositingCheap()) {
RefPtr<PersistentBufferProvider> provider =
PersistentBufferProviderShared::Create(aSize, aFormat,
AsShadowForwarder());

Просмотреть файл

@ -9,6 +9,7 @@
#include "Layers.h" // for Layer, etc
#include "gfx2DGlue.h"
#include "gfxPlatform.h" // for gfxPlatform
#include "MainThreadUtils.h"
#include "mozilla/Atomics.h"
#include "mozilla/StaticPrefs.h"
#include "mozilla/SystemGroup.h"
@ -235,6 +236,155 @@ class TextureChild final : PTextureChild {
friend void DeallocateTextureClient(TextureDeallocParams params);
};
static inline gfx::BackendType
BackendTypeForBackendSelector(LayersBackend aLayersBackend, BackendSelector aSelector)
{
switch (aSelector) {
case BackendSelector::Canvas:
return gfxPlatform::GetPlatform()->GetPreferredCanvasBackend();
case BackendSelector::Content:
return gfxPlatform::GetPlatform()->GetContentBackendFor(aLayersBackend);
default:
MOZ_ASSERT_UNREACHABLE("Unknown backend selector");
return gfx::BackendType::NONE;
}
};
static TextureType
GetTextureType(gfx::SurfaceFormat aFormat, gfx::IntSize aSize,
LayersBackend aLayersBackend, gfx::BackendType aBackendType,
int32_t aMaxTextureSize, TextureAllocationFlags aAllocFlags)
{
#ifdef XP_WIN
if ((aLayersBackend == LayersBackend::LAYERS_D3D11 ||
aLayersBackend == LayersBackend::LAYERS_WR) &&
(aBackendType == gfx::BackendType::DIRECT2D ||
aBackendType == gfx::BackendType::DIRECT2D1_1 ||
(!!(aAllocFlags & ALLOC_FOR_OUT_OF_BAND_CONTENT) &&
DeviceManagerDx::Get()->GetContentDevice())) &&
aSize.width <= aMaxTextureSize &&
aSize.height <= aMaxTextureSize &&
!(aAllocFlags & ALLOC_UPDATE_FROM_SURFACE)) {
return TextureType::D3D11;
}
if (aLayersBackend != LayersBackend::LAYERS_WR &&
aFormat == SurfaceFormat::B8G8R8X8 &&
aBackendType == gfx::BackendType::CAIRO &&
NS_IsMainThread()) {
return TextureType::DIB;
}
#endif
#ifdef MOZ_X11
gfxSurfaceType type =
gfxPlatform::GetPlatform()->ScreenReferenceSurface()->GetType();
if (aLayersBackend == LayersBackend::LAYERS_BASIC &&
aBackendType == gfx::BackendType::CAIRO &&
type == gfxSurfaceType::Xlib) {
return TextureType::X11;
}
if (aLayersBackend == LayersBackend::LAYERS_OPENGL &&
type == gfxSurfaceType::Xlib &&
aFormat != SurfaceFormat::A8 &&
gl::sGLXLibrary.UseTextureFromPixmap()) {
return TextureType::X11;
}
#endif
#ifdef XP_MACOSX
if (StaticPrefs::UseIOSurfaceTextures()) {
return TextureType::MacIOSurface;
}
#endif
#ifdef MOZ_WIDGET_ANDROID
if (StaticPrefs::UseSurfaceTextureTextures()) {
return TextureType::AndroidNativeWindow;
}
#endif
return TextureType::Unknown;
}
static bool
ShouldRemoteTextureType(TextureType aTextureType, BackendSelector aSelector)
{
if (!XRE_IsContentProcess()) {
return false;
}
if (aSelector != BackendSelector::Canvas || !gfxVars::RemoteCanvasEnabled()) {
return false;
}
switch (aTextureType) {
case TextureType::D3D11:
return true;
default:
return false;
}
}
/* static */
TextureData*
TextureData::Create(TextureForwarder* aAllocator, gfx::SurfaceFormat aFormat,
gfx::IntSize aSize, LayersBackend aLayersBackend,
int32_t aMaxTextureSize, BackendSelector aSelector,
TextureFlags aTextureFlags,
TextureAllocationFlags aAllocFlags)
{
gfx::BackendType moz2DBackend =
BackendTypeForBackendSelector(aLayersBackend, aSelector);
TextureType textureType = GetTextureType(aFormat, aSize, aLayersBackend,
moz2DBackend, aMaxTextureSize,
aAllocFlags);
if (ShouldRemoteTextureType(textureType, aSelector)) {
// TODO: return a recording texture data here.
}
switch(textureType) {
#ifdef XP_WIN
case TextureType::D3D11:
return D3D11TextureData::Create(aSize, aFormat, aAllocFlags);
case TextureType::DIB:
return DIBTextureData::Create(aSize, aFormat, aAllocator);
#endif
#ifdef MOZ_X11
case TextureType::X11:
return X11TextureData::Create(aSize, aFormat, aTextureFlags, aAllocator);
#endif
#ifdef XP_MACOSX
case TextureType::MacIOSurface:
return MacIOSurfaceTextureData::Create(aSize, aFormat, moz2DBackend);
#endif
#ifdef MOZ_WIDGET_ANDROID
case TextureType::AndroidNativeWindow:
return AndroidNativeWindowTextureData::Create(aSize, aFormat);
#endif
default:
return nullptr;
}
}
/* static */
bool
TextureData::IsRemote(LayersBackend aLayersBackend, BackendSelector aSelector)
{
gfx::BackendType moz2DBackend =
BackendTypeForBackendSelector(aLayersBackend, aSelector);
TextureType textureType =
GetTextureType(gfx::SurfaceFormat::UNKNOWN, gfx::IntSize(1,1),
aLayersBackend, moz2DBackend, INT32_MAX,
TextureAllocationFlags::ALLOC_DEFAULT);
return ShouldRemoteTextureType(textureType, aSelector);
}
static void DestroyTextureData(TextureData* aTextureData,
LayersIPCChannel* aAllocator, bool aDeallocate,
bool aMainThreadOnly) {
@ -996,19 +1146,6 @@ bool TextureClient::InitIPDLActor(KnowsCompositor* aForwarder) {
PTextureChild* TextureClient::GetIPDLActor() { return mActor; }
static inline gfx::BackendType BackendTypeForBackendSelector(
LayersBackend aLayersBackend, BackendSelector aSelector) {
switch (aSelector) {
case BackendSelector::Canvas:
return gfxPlatform::GetPlatform()->GetPreferredCanvasBackend();
case BackendSelector::Content:
return gfxPlatform::GetPlatform()->GetContentBackendFor(aLayersBackend);
default:
MOZ_ASSERT_UNREACHABLE("Unknown backend selector");
return gfx::BackendType::NONE;
}
};
// static
already_AddRefed<TextureClient> TextureClient::CreateForDrawing(
KnowsCompositor* aAllocator, gfx::SurfaceFormat aFormat, gfx::IntSize aSize,
@ -1043,53 +1180,9 @@ already_AddRefed<TextureClient> TextureClient::CreateForDrawing(
return nullptr;
}
TextureData* data = nullptr;
#ifdef XP_WIN
if ((aLayersBackend == LayersBackend::LAYERS_D3D11 ||
aLayersBackend == LayersBackend::LAYERS_WR) &&
(moz2DBackend == gfx::BackendType::DIRECT2D ||
moz2DBackend == gfx::BackendType::DIRECT2D1_1 ||
(!!(aAllocFlags & ALLOC_FOR_OUT_OF_BAND_CONTENT) &&
DeviceManagerDx::Get()->GetContentDevice())) &&
aSize.width <= aMaxTextureSize && aSize.height <= aMaxTextureSize &&
!(aAllocFlags & ALLOC_UPDATE_FROM_SURFACE)) {
data = D3D11TextureData::Create(aSize, aFormat, aAllocFlags);
}
if (aLayersBackend != LayersBackend::LAYERS_WR && !data &&
aFormat == SurfaceFormat::B8G8R8X8 &&
moz2DBackend == gfx::BackendType::CAIRO && NS_IsMainThread()) {
data = DIBTextureData::Create(aSize, aFormat, aAllocator);
}
#endif
#ifdef MOZ_X11
gfxSurfaceType type =
gfxPlatform::GetPlatform()->ScreenReferenceSurface()->GetType();
if (!data && aLayersBackend == LayersBackend::LAYERS_BASIC &&
moz2DBackend == gfx::BackendType::CAIRO && type == gfxSurfaceType::Xlib) {
data = X11TextureData::Create(aSize, aFormat, aTextureFlags, aAllocator);
}
if (!data && aLayersBackend == LayersBackend::LAYERS_OPENGL &&
type == gfxSurfaceType::Xlib && aFormat != SurfaceFormat::A8 &&
gl::sGLXLibrary.UseTextureFromPixmap()) {
data = X11TextureData::Create(aSize, aFormat, aTextureFlags, aAllocator);
}
#endif
#ifdef XP_MACOSX
if (!data && StaticPrefs::UseIOSurfaceTextures()) {
data = MacIOSurfaceTextureData::Create(aSize, aFormat, moz2DBackend);
}
#endif
#ifdef MOZ_WIDGET_ANDROID
if (!data && StaticPrefs::UseSurfaceTextureTextures()) {
data = AndroidNativeWindowTextureData::Create(aSize, aFormat);
}
#endif
TextureData* data =
TextureData::Create(aAllocator, aFormat, aSize, aLayersBackend,
aMaxTextureSize, aSelector, aTextureFlags, aAllocFlags);
if (data) {
return MakeAndAddRef<TextureClient>(data, aTextureFlags, aAllocator);

Просмотреть файл

@ -245,7 +245,16 @@ class TextureData {
canConcurrentlyReadLock(true) {}
};
TextureData() { MOZ_COUNT_CTOR(TextureData); }
static TextureData* Create(TextureForwarder* aAllocator,
gfx::SurfaceFormat aFormat,
gfx::IntSize aSize,
LayersBackend aLayersBackend,
int32_t aMaxTextureSize,
BackendSelector aSelector,
TextureFlags aTextureFlags,
TextureAllocationFlags aAllocFlags);
static bool IsRemote(LayersBackend aLayersBackend, BackendSelector aSelector);
virtual ~TextureData() { MOZ_COUNT_DTOR(TextureData); }
@ -300,6 +309,9 @@ class TextureData {
virtual BufferTextureData* AsBufferTextureData() { return nullptr; }
virtual GPUVideoTextureData* AsGPUVideoTextureData() { return nullptr; }
protected:
TextureData() { MOZ_COUNT_CTOR(TextureData); }
};
/**

Просмотреть файл

@ -82,6 +82,13 @@ struct ParamTraits<mozilla::layers::LayersBackend>
mozilla::layers::LayersBackend::LAYERS_NONE,
mozilla::layers::LayersBackend::LAYERS_LAST> {};
template <>
struct ParamTraits<mozilla::layers::TextureType>
: public ContiguousEnumSerializer<
mozilla::layers::TextureType,
mozilla::layers::TextureType::Unknown,
mozilla::layers::TextureType::Last> {};
template <>
struct ParamTraits<mozilla::layers::ScaleMode>
: public ContiguousEnumSerializerInclusive<

Просмотреть файл

@ -734,14 +734,13 @@ WebRenderLayerManager::CreatePersistentBufferProvider(
// initialized with WebRender to reduce memory usage.
gfxPlatform::GetPlatform()->EnsureDevicesInitialized();
if (StaticPrefs::PersistentBufferProviderSharedEnabled()) {
RefPtr<PersistentBufferProvider> provider =
PersistentBufferProviderShared::Create(aSize, aFormat,
AsKnowsCompositor());
if (provider) {
return provider.forget();
}
RefPtr<PersistentBufferProvider> provider =
PersistentBufferProviderShared::Create(aSize, aFormat,
AsKnowsCompositor());
if (provider) {
return provider.forget();
}
return LayerManager::CreatePersistentBufferProvider(aSize, aFormat);
}

Просмотреть файл

@ -2423,6 +2423,9 @@ void gfxPlatform::InitAcceleration() {
VideoDecodingFailedChangedCallback,
"media.hardware-video-decoding.failed");
InitGPUProcessPrefs();
gfxVars::SetRemoteCanvasEnabled(StaticPrefs::CanvasRemote() &&
gfxConfig::IsEnabled(Feature::GPU_PROCESS));
}
}
@ -3394,6 +3397,8 @@ void gfxPlatform::NotifyGPUProcessDisabled() {
NS_LITERAL_CSTRING("FEATURE_FAILURE_GPU_PROCESS_DISABLED"));
gfxVars::SetUseWebRender(false);
}
gfxVars::SetRemoteCanvasEnabled(false);
}
void gfxPlatform::FetchAndImportContentDeviceData() {

Просмотреть файл

@ -2525,6 +2525,13 @@ VARCACHE_PREF(
RelaxedAtomicInt32, 0x7fff
)
VARCACHE_PREF(
Live,
"gfx.canvas.remote",
CanvasRemote,
RelaxedAtomicBool, false
)
VARCACHE_PREF(
Live,
"gfx.color_management.enablev4",

Просмотреть файл

@ -839,6 +839,7 @@ pref("gfx.font_ahem_antialias_none", false);
// e.g., pref("gfx.canvas.azure.backends", "direct2d,skia,cairo");
pref("gfx.canvas.azure.backends", "direct2d1.1,skia,cairo");
pref("gfx.content.azure.backends", "direct2d1.1,skia,cairo");
pref("gfx.canvas.remote", false);
#else
#ifdef XP_MACOSX
pref("gfx.content.azure.backends", "skia");