Bug 1343764 - Add ExternalBuffer handling r=nical

This commit is contained in:
sotaro 2017-03-07 19:37:28 +09:00
parent 900393a0dc
commit 1d710a54ef
31 changed files with 625 additions and 97 deletions

View File

@ -69,10 +69,12 @@ enum class TextureFlags : uint32_t {
// This flag is only used in the parent process.
INVALID_COMPOSITOR = 1 << 12,
// The texture was created by converting from YCBCR to RGB
RGB_FROM_YCBCR = 1 << 13,
RGB_FROM_YCBCR = 1 << 13,
// The texture is used for snapshot.
SNAPSHOT = 1 << 14,
// OR union of all valid bits
ALL_BITS = (1 << 14) - 1,
ALL_BITS = (1 << 15) - 1,
// the default flags
DEFAULT = NO_FLAGS
};

View File

@ -17,6 +17,7 @@ namespace layers {
already_AddRefed<TextureHost>
CreateTextureHostBasic(const SurfaceDescriptor& aDesc,
ISurfaceAllocator* aDeallocator,
LayersBackend aBackend,
TextureFlags aFlags)
{
#ifdef XP_MACOSX
@ -26,7 +27,7 @@ CreateTextureHostBasic(const SurfaceDescriptor& aDesc,
return MakeAndAddRef<MacIOSurfaceTextureHostBasic>(aFlags, desc);
}
#endif
return CreateBackendIndependentTextureHost(aDesc, aDeallocator, aFlags);
return CreateBackendIndependentTextureHost(aDesc, aDeallocator, aBackend, aFlags);
}
} // namespace layers

View File

@ -43,6 +43,7 @@ class Compositor;
class ThebesBufferData;
class TiledContentHost;
class CompositableParentManager;
class WebRenderImageHost;
struct EffectChain;
struct ImageCompositeNotificationInfo {
@ -148,6 +149,7 @@ public:
void SetLayer(Layer* aLayer) { mLayer = aLayer; }
virtual TiledContentHost* AsTiledContentHost() { return nullptr; }
virtual WebRenderImageHost* AsWebRenderImageHost() { return nullptr; }
typedef uint32_t AttachFlags;
static const AttachFlags NO_FLAGS = 0;

View File

@ -9,6 +9,7 @@
#include "LayerScope.h"
#include "LayersLogging.h" // for AppendToString
#include "mozilla/gfx/2D.h" // for DataSourceSurface, Factory
#include "mozilla/gfx/gfxVars.h"
#include "mozilla/ipc/Shmem.h" // for Shmem
#include "mozilla/layers/CompositableTransactionParent.h" // for CompositableParentManager
#include "mozilla/layers/CompositorBridgeParent.h"
@ -20,6 +21,7 @@
#include "mozilla/layers/ImageDataSerializer.h"
#include "mozilla/layers/TextureClient.h"
#include "mozilla/layers/GPUVideoTextureHost.h"
#include "mozilla/layers/WebRenderTextureHost.h"
#include "nsAString.h"
#include "mozilla/RefPtr.h" // for nsRefPtr
#include "nsPrintfCString.h" // for nsPrintfCString
@ -160,23 +162,27 @@ TextureHost::SetLastFwdTransactionId(uint64_t aTransactionId)
// implemented in TextureHostOGL.cpp
already_AddRefed<TextureHost> CreateTextureHostOGL(const SurfaceDescriptor& aDesc,
ISurfaceAllocator* aDeallocator,
TextureFlags aFlags);
ISurfaceAllocator* aDeallocator,
LayersBackend aBackend,
TextureFlags aFlags);
// implemented in TextureHostBasic.cpp
already_AddRefed<TextureHost> CreateTextureHostBasic(const SurfaceDescriptor& aDesc,
ISurfaceAllocator* aDeallocator,
TextureFlags aFlags);
ISurfaceAllocator* aDeallocator,
LayersBackend aBackend,
TextureFlags aFlags);
// implemented in TextureD3D11.cpp
already_AddRefed<TextureHost> CreateTextureHostD3D11(const SurfaceDescriptor& aDesc,
ISurfaceAllocator* aDeallocator,
TextureFlags aFlags);
ISurfaceAllocator* aDeallocator,
LayersBackend aBackend,
TextureFlags aFlags);
// implemented in TextureD3D9.cpp
already_AddRefed<TextureHost> CreateTextureHostD3D9(const SurfaceDescriptor& aDesc,
ISurfaceAllocator* aDeallocator,
TextureFlags aFlags);
ISurfaceAllocator* aDeallocator,
LayersBackend aBackend,
TextureFlags aFlags);
already_AddRefed<TextureHost>
TextureHost::Create(const SurfaceDescriptor& aDesc,
@ -189,19 +195,19 @@ TextureHost::Create(const SurfaceDescriptor& aDesc,
case SurfaceDescriptor::TSurfaceDescriptorDIB:
case SurfaceDescriptor::TSurfaceDescriptorFileMapping:
case SurfaceDescriptor::TSurfaceDescriptorGPUVideo:
return CreateBackendIndependentTextureHost(aDesc, aDeallocator, aFlags);
return CreateBackendIndependentTextureHost(aDesc, aDeallocator, aBackend, aFlags);
case SurfaceDescriptor::TEGLImageDescriptor:
case SurfaceDescriptor::TSurfaceTextureDescriptor:
case SurfaceDescriptor::TSurfaceDescriptorSharedGLTexture:
return CreateTextureHostOGL(aDesc, aDeallocator, aFlags);
return CreateTextureHostOGL(aDesc, aDeallocator, aBackend, aFlags);
case SurfaceDescriptor::TSurfaceDescriptorMacIOSurface:
if (aBackend == LayersBackend::LAYERS_OPENGL ||
aBackend == LayersBackend::LAYERS_WR) {
return CreateTextureHostOGL(aDesc, aDeallocator, aFlags);
return CreateTextureHostOGL(aDesc, aDeallocator, aBackend, aFlags);
} else {
return CreateTextureHostBasic(aDesc, aDeallocator, aFlags);
return CreateTextureHostBasic(aDesc, aDeallocator, aBackend, aFlags);
}
#ifdef MOZ_X11
@ -213,14 +219,14 @@ TextureHost::Create(const SurfaceDescriptor& aDesc,
#ifdef XP_WIN
case SurfaceDescriptor::TSurfaceDescriptorD3D9:
return CreateTextureHostD3D9(aDesc, aDeallocator, aFlags);
return CreateTextureHostD3D9(aDesc, aDeallocator, aBackend, aFlags);
case SurfaceDescriptor::TSurfaceDescriptorD3D10:
case SurfaceDescriptor::TSurfaceDescriptorDXGIYCbCr:
if (aBackend == LayersBackend::LAYERS_D3D9) {
return CreateTextureHostD3D9(aDesc, aDeallocator, aFlags);
return CreateTextureHostD3D9(aDesc, aDeallocator, aBackend, aFlags);
} else {
return CreateTextureHostD3D11(aDesc, aDeallocator, aFlags);
return CreateTextureHostD3D11(aDesc, aDeallocator, aBackend, aFlags);
}
#endif
default:
@ -228,9 +234,21 @@ TextureHost::Create(const SurfaceDescriptor& aDesc,
}
}
bool WrapWithWebRenderTextureHost(LayersBackend aBackend,
TextureFlags aFlags)
{
if (!gfxVars::UseWebRender() ||
(aFlags & TextureFlags::SNAPSHOT) ||
(aBackend != LayersBackend::LAYERS_WR)) {
return false;
}
return true;
}
already_AddRefed<TextureHost>
CreateBackendIndependentTextureHost(const SurfaceDescriptor& aDesc,
ISurfaceAllocator* aDeallocator,
LayersBackend aBackend,
TextureFlags aFlags)
{
RefPtr<TextureHost> result;
@ -244,12 +262,18 @@ CreateBackendIndependentTextureHost(const SurfaceDescriptor& aDesc,
bufferDesc.desc(),
aDeallocator,
aFlags);
if (WrapWithWebRenderTextureHost(aBackend, aFlags)) {
result = new WebRenderTextureHost(aFlags, result);
}
break;
}
case MemoryOrShmem::Tuintptr_t: {
result = new MemoryTextureHost(reinterpret_cast<uint8_t*>(data.get_uintptr_t()),
bufferDesc.desc(),
aFlags);
if (WrapWithWebRenderTextureHost(aBackend, aFlags)) {
result = new WebRenderTextureHost(aFlags, result);
}
break;
}
default:

View File

@ -55,6 +55,7 @@ class TextureSourceBasic;
class DataTextureSource;
class PTextureParent;
class TextureParent;
class WebRenderTextureHost;
class WrappingTextureSourceYCbCrBasic;
/**
@ -586,6 +587,8 @@ public:
virtual BufferTextureHost* AsBufferTextureHost() { return nullptr; }
virtual WebRenderTextureHost* AsWebRenderTextureHost() { return nullptr; }
protected:
void ReadUnlock();
@ -882,6 +885,7 @@ private:
already_AddRefed<TextureHost>
CreateBackendIndependentTextureHost(const SurfaceDescriptor& aDesc,
ISurfaceAllocator* aDeallocator,
LayersBackend aBackend,
TextureFlags aFlags);
} // namespace layers

View File

@ -629,12 +629,13 @@ DXGIYCbCrTextureData::Deallocate(LayersIPCChannel*)
already_AddRefed<TextureHost>
CreateTextureHostD3D11(const SurfaceDescriptor& aDesc,
ISurfaceAllocator* aDeallocator,
LayersBackend aBackend,
TextureFlags aFlags)
{
RefPtr<TextureHost> result;
switch (aDesc.type()) {
case SurfaceDescriptor::TSurfaceDescriptorBuffer: {
result = CreateBackendIndependentTextureHost(aDesc, aDeallocator, aFlags);
result = CreateBackendIndependentTextureHost(aDesc, aDeallocator, aBackend, aFlags);
break;
}
case SurfaceDescriptor::TSurfaceDescriptorD3D10: {

View File

@ -49,12 +49,13 @@ TextureSourceD3D9::~TextureSourceD3D9()
already_AddRefed<TextureHost>
CreateTextureHostD3D9(const SurfaceDescriptor& aDesc,
ISurfaceAllocator* aDeallocator,
LayersBackend aBackend,
TextureFlags aFlags)
{
RefPtr<TextureHost> result;
switch (aDesc.type()) {
case SurfaceDescriptor::TSurfaceDescriptorBuffer: {
result = CreateBackendIndependentTextureHost(aDesc, aDeallocator, aFlags);
result = CreateBackendIndependentTextureHost(aDesc, aDeallocator, aBackend, aFlags);
break;
}
case SurfaceDescriptor::TSurfaceDescriptorD3D9: {

View File

@ -222,7 +222,7 @@ CrossProcessCompositorBridgeParent::AllocPWebRenderBridgeParent(const wr::Pipeli
WebRenderBridgeParent* parent = nullptr;
RefPtr<wr::WebRenderAPI> api = root->GetWebRenderAPI();
RefPtr<WebRenderCompositableHolder> holder = root->CompositableHolder();
RefPtr<WebRenderCompositableHolder> holder = new WebRenderCompositableHolder();
parent = new WebRenderBridgeParent(this, aPipelineId, nullptr, root->CompositorScheduler(), Move(api), Move(holder));
parent->AddRef(); // IPDL reference

View File

@ -97,6 +97,8 @@ public:
virtual bool UsesImageBridge() const { return false; }
virtual bool UsesWebRenderBridge() const { return false; }
protected:
void Finalize() {}

View File

@ -215,6 +215,7 @@ EXPORTS.mozilla.layers += [
'wr/WebRenderLayerManager.h',
'wr/WebRenderLayersLogging.h',
'wr/WebRenderMessageUtils.h',
'wr/WebRenderTextureHost.h',
]
if CONFIG['MOZ_X11']:
@ -405,6 +406,7 @@ UNIFIED_SOURCES += [
'wr/WebRenderLayersLogging.cpp',
'wr/WebRenderPaintedLayer.cpp',
'wr/WebRenderTextLayer.cpp',
'wr/WebRenderTextureHost.cpp',
]
SOURCES += [

View File

@ -40,13 +40,16 @@ class Compositor;
already_AddRefed<TextureHost>
CreateTextureHostOGL(const SurfaceDescriptor& aDesc,
ISurfaceAllocator* aDeallocator,
LayersBackend aBackend,
TextureFlags aFlags)
{
RefPtr<TextureHost> result;
switch (aDesc.type()) {
case SurfaceDescriptor::TSurfaceDescriptorBuffer: {
result = CreateBackendIndependentTextureHost(aDesc,
aDeallocator, aFlags);
aDeallocator,
aBackend,
aFlags);
break;
}

View File

@ -18,6 +18,7 @@
#include "mozilla/layers/ImageDataSerializer.h"
#include "mozilla/layers/TextureHost.h"
#include "mozilla/layers/WebRenderCompositableHolder.h"
#include "mozilla/layers/WebRenderTextureHost.h"
#include "mozilla/webrender/RenderThread.h"
#include "mozilla/widget/CompositorWidget.h"
@ -293,10 +294,31 @@ WebRenderBridgeParent::ProcessWebrenderCommands(const gfx::IntSize &aSize,
switch (cmd.type()) {
case WebRenderParentCommand::TOpAddExternalImage: {
const OpAddExternalImage& op = cmd.get_OpAddExternalImage();
wr::ImageKey key = op.key();
MOZ_ASSERT(mExternalImageIds.Get(op.externalImageId()).get());
RefPtr<CompositableHost> host = mExternalImageIds.Get(op.externalImageId());
if (!host) {
NS_ERROR("CompositableHost does not exist");
break;
}
// XXX select Texture for video in CompositeToTarget().
TextureHost* texture = host->GetAsTextureHost();
if (!texture) {
NS_ERROR("TextureHost does not exist");
break;
}
WebRenderTextureHost* wrTexture = texture->AsWebRenderTextureHost();
if (wrTexture) {
// XXX handling YUV
gfx::SurfaceFormat format =
wrTexture->GetFormat() == SurfaceFormat::YUV ? SurfaceFormat::B8G8R8A8 : wrTexture->GetFormat();
mApi->AddExternalImageBuffer(key,
wrTexture->GetSize(),
format,
wrTexture->GetExternalImageKey());
mCompositableHolder->HoldExternalImage(aEpoch, texture->AsWebRenderTextureHost());
keysToDelete.push_back(key);
break;
}
RefPtr<DataSourceSurface> dSurf = host->GetAsSurface();
@ -311,7 +333,6 @@ WebRenderBridgeParent::ProcessWebrenderCommands(const gfx::IntSize &aSize,
IntSize size = dSurf->GetSize();
wr::ImageDescriptor descriptor(size, map.mStride, SurfaceFormat::B8G8R8A8);
wr::ImageKey key = op.key();
auto slice = Range<uint8_t>(map.mData, size.height * map.mStride);
mApi->AddImage(key, descriptor, slice);
@ -431,7 +452,6 @@ WebRenderBridgeParent::RecvAddExternalImageId(const uint64_t& aImageId,
return IPC_OK();
}
mCompositableHolder->AddExternalImageId(aImageId, host);
mExternalImageIds.Put(aImageId, host);
return IPC_OK();
@ -454,7 +474,6 @@ WebRenderBridgeParent::RecvAddExternalImageIdForCompositable(const uint64_t& aIm
return IPC_OK();
}
mCompositableHolder->AddExternalImageId(aImageId, host);
mExternalImageIds.Put(aImageId, host);
return IPC_OK();
@ -468,7 +487,6 @@ WebRenderBridgeParent::RecvRemoveExternalImageId(const uint64_t& aImageId)
}
MOZ_ASSERT(mExternalImageIds.Get(aImageId).get());
mExternalImageIds.Remove(aImageId);
mCompositableHolder->RemoveExternalImageId(aImageId);
return IPC_OK();
}
@ -534,8 +552,6 @@ WebRenderBridgeParent::FlushPendingTransactionIds()
return id;
}
uint64_t
WebRenderBridgeParent::FlushTransactionIdsForEpoch(const wr::Epoch& aEpoch)
{
@ -548,6 +564,9 @@ WebRenderBridgeParent::FlushTransactionIdsForEpoch(const wr::Epoch& aEpoch)
}
mPendingTransactionIds.pop();
}
mCompositableHolder->Update(aEpoch);
return id;
}
@ -578,14 +597,15 @@ WebRenderBridgeParent::ClearResources()
if (mApi) {
++mWrEpoch; // Update webrender epoch
mApi->ClearRootDisplayList(wr::NewEpoch(mWrEpoch), mPipelineId);
}
DeleteOldImages();
if (mCompositableHolder) {
for (auto iter = mExternalImageIds.Iter(); !iter.Done(); iter.Next()) {
uint64_t externalImageId = iter.Key();
mCompositableHolder->RemoveExternalImageId(externalImageId);
if (!mKeysToDelete.empty()) {
// XXX Sync wait.
mApi->WaitFlushed();
DeleteOldImages();
}
}
if (mCompositableHolder) {
mCompositableHolder->Destroy();
}
mExternalImageIds.Clear();
if (mWidget && mCompositorScheduler) {

View File

@ -6,7 +6,8 @@
#include "WebRenderCompositableHolder.h"
#include "CompositableHost.h"
//#include "mozilla/layers/CompositorBridgeParent.h"
#include "mozilla/layers/WebRenderImageHost.h"
#include "mozilla/layers/WebRenderTextureHost.h"
namespace mozilla {
@ -22,36 +23,36 @@ WebRenderCompositableHolder::WebRenderCompositableHolder()
WebRenderCompositableHolder::~WebRenderCompositableHolder()
{
MOZ_COUNT_DTOR(WebRenderCompositableHolder);
Destroy();
MOZ_ASSERT(mWebRenderTextureHosts.empty());
}
void
WebRenderCompositableHolder::Destroy()
{
mCompositableHosts.Clear();
while (!mWebRenderTextureHosts.empty()) {
mWebRenderTextureHosts.pop();
}
}
void
WebRenderCompositableHolder::AddExternalImageId(uint64_t aExternalImageId, CompositableHost* aHost)
WebRenderCompositableHolder::HoldExternalImage(const wr::Epoch& aEpoch, WebRenderTextureHost* aTexture)
{
MOZ_ASSERT(!mCompositableHosts.Get(aExternalImageId));
mCompositableHosts.Put(aExternalImageId, aHost);
MOZ_ASSERT(aTexture);
// Hold WebRenderTextureHost until end of its usage on RenderThread
mWebRenderTextureHosts.push(ForwardingTextureHosts(aEpoch, aTexture));
}
void
WebRenderCompositableHolder::RemoveExternalImageId(uint64_t aExternalImageId)
WebRenderCompositableHolder::Update(const wr::Epoch& aEpoch)
{
MOZ_ASSERT(mCompositableHosts.Get(aExternalImageId));
mCompositableHosts.Remove(aExternalImageId);
}
void
WebRenderCompositableHolder::UpdateExternalImages()
{
for (auto iter = mCompositableHosts.Iter(); !iter.Done(); iter.Next()) {
RefPtr<CompositableHost>& host = iter.Data();
// XXX Change to correct TextrueSource handling here.
host->BindTextureSource();
if (mWebRenderTextureHosts.empty()) {
return;
}
while (!mWebRenderTextureHosts.empty()) {
if (aEpoch <= mWebRenderTextureHosts.front().mEpoch) {
break;
}
mWebRenderTextureHosts.pop();
}
}

View File

@ -6,12 +6,21 @@
#ifndef MOZILLA_GFX_WEBRENDERCOMPOSITABLE_HOLDER_H
#define MOZILLA_GFX_WEBRENDERCOMPOSITABLE_HOLDER_H
#include "nsDataHashtable.h"
#include <queue>
#include "mozilla/layers/TextureHost.h"
#include "mozilla/webrender/WebRenderTypes.h"
namespace mozilla {
namespace wr {
class WebRenderAPI;
}
namespace layers {
class CompositableHost;
class WebRenderTextureHost;
class WebRenderCompositableHolder final
{
@ -21,20 +30,26 @@ public:
explicit WebRenderCompositableHolder();
protected:
virtual ~WebRenderCompositableHolder();
~WebRenderCompositableHolder();
public:
virtual void Destroy();
void AddExternalImageId(uint64_t aExternalImageId, CompositableHost* aHost);
void RemoveExternalImageId(uint64_t aExternalImageId);
void UpdateExternalImages();
void Destroy();
void HoldExternalImage(const wr::Epoch& aEpoch, WebRenderTextureHost* aTexture);
void Update(const wr::Epoch& aEpoch);
private:
// Holds CompositableHosts that are bound to external image ids.
nsDataHashtable<nsUint64HashKey, RefPtr<CompositableHost> > mCompositableHosts;
struct ForwardingTextureHosts {
ForwardingTextureHosts(const wr::Epoch& aEpoch, TextureHost* aTexture)
: mEpoch(aEpoch)
, mTexture(aTexture)
{}
wr::Epoch mEpoch;
CompositableTextureHostRef mTexture;
};
// Holds forwarding WebRenderTextureHosts.
std::queue<ForwardingTextureHosts> mWebRenderTextureHosts;
};
} // namespace layers

View File

@ -102,7 +102,10 @@ WebRenderImageHost::GetCompositionTime() const
TextureHost*
WebRenderImageHost::GetAsTextureHost(IntRect* aPictureRect)
{
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
TimedImage* img = ChooseImage();
if (img) {
return img->mTextureHost;
}
return nullptr;
}

View File

@ -62,6 +62,8 @@ public:
virtual void CleanupResources() override;
virtual WebRenderImageHost* AsWebRenderImageHost() override { return this; }
protected:
// ImageComposite
virtual TimeStamp GetCompositionTime() const override;

View File

@ -348,7 +348,7 @@ WebRenderLayerManager::MakeSnapshotIfRequired(LayoutDeviceIntSize aSize)
SurfaceFormat::B8G8R8A8,
aSize.ToUnknownSize(),
BackendType::SKIA,
TextureFlags::DEFAULT);
TextureFlags::SNAPSHOT);
if (!texture) {
return;
}

View File

@ -0,0 +1,109 @@
/* -*- 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 "WebRenderTextureHost.h"
#include "mozilla/webrender/RenderTextureHost.h"
#include "mozilla/webrender/RenderThread.h"
namespace mozilla {
namespace layers {
uint64_t WebRenderTextureHost::sSerialCounter(0);
WebRenderTextureHost::WebRenderTextureHost(TextureFlags aFlags,
TextureHost* aTexture)
: TextureHost(aFlags)
, mExternalImageId(++sSerialCounter)
{
MOZ_COUNT_CTOR(WebRenderTextureHost);
mWrappedTextureHost = aTexture;
// XXX support only BufferTextureHost for now.
BufferTextureHost* bufferTexture = aTexture->AsBufferTextureHost();
MOZ_ASSERT(bufferTexture);
RefPtr<wr::RenderTextureHost> texture =
new wr::RenderTextureHost(bufferTexture->GetBuffer(),
bufferTexture->GetBufferDescriptor());
wr::RenderThread::Get()->RegisterExternalImage(mExternalImageId, texture);
}
WebRenderTextureHost::~WebRenderTextureHost()
{
MOZ_COUNT_DTOR(WebRenderTextureHost);
wr::RenderThread::Get()->UnregisterExternalImage(mExternalImageId);
}
bool
WebRenderTextureHost::Lock()
{
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
return false;
}
void
WebRenderTextureHost::Unlock()
{
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
return;
}
bool
WebRenderTextureHost::BindTextureSource(CompositableTextureSourceRef& aTexture)
{
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
return false;
}
already_AddRefed<gfx::DataSourceSurface>
WebRenderTextureHost::GetAsSurface()
{
if (!mWrappedTextureHost) {
return nullptr;
}
return mWrappedTextureHost->GetAsSurface();
}
Compositor*
WebRenderTextureHost::GetCompositor()
{
//MOZ_ASSERT_UNREACHABLE("unexpected to be called");
return nullptr;
}
void
WebRenderTextureHost::SetCompositor(Compositor* aCompositor)
{
}
YUVColorSpace
WebRenderTextureHost::GetYUVColorSpace() const
{
if (mWrappedTextureHost) {
return mWrappedTextureHost->GetYUVColorSpace();
}
return YUVColorSpace::UNKNOWN;
}
gfx::IntSize
WebRenderTextureHost::GetSize() const
{
if (!mWrappedTextureHost) {
return gfx::IntSize();
}
return mWrappedTextureHost->GetSize();
}
gfx::SurfaceFormat
WebRenderTextureHost::GetFormat() const
{
if (!mWrappedTextureHost) {
return gfx::SurfaceFormat::UNKNOWN;
}
return mWrappedTextureHost->GetFormat();
}
} // namespace layers
} // namespace mozilla

View File

@ -0,0 +1,58 @@
/* -*- 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_WEBRENDERTEXTUREHOST_H
#define MOZILLA_GFX_WEBRENDERTEXTUREHOST_H
#include "mozilla/layers/TextureHost.h"
namespace mozilla {
namespace layers {
class WebRenderTextureHost : public TextureHost
{
public:
WebRenderTextureHost(TextureFlags aFlags,
TextureHost* aTexture);
virtual ~WebRenderTextureHost();
virtual void DeallocateDeviceData() override {}
virtual void SetCompositor(Compositor* aCompositor) override;
virtual Compositor* GetCompositor() override;
virtual bool Lock() override;
virtual void Unlock() override;
virtual gfx::SurfaceFormat GetFormat() const override;
virtual bool BindTextureSource(CompositableTextureSourceRef& aTexture) override;
virtual already_AddRefed<gfx::DataSourceSurface> GetAsSurface() override;
virtual YUVColorSpace GetYUVColorSpace() const override;
virtual gfx::IntSize GetSize() const override;
#ifdef MOZ_LAYERS_HAVE_LOG
virtual const char* Name() override { return "WebRenderTextureHost"; }
#endif
virtual WebRenderTextureHost* AsWebRenderTextureHost() override { return this; }
uint64_t GetExternalImageKey() { return mExternalImageId; }
protected:
RefPtr<TextureHost> mWrappedTextureHost;
uint64_t mExternalImageId;
static uint64_t sSerialCounter;
};
} // namespace layers
} // namespace mozilla
#endif // MOZILLA_GFX_WEBRENDERTEXTUREHOST_H

View File

@ -148,6 +148,7 @@ void TestTextureClientSurface(TextureClient* texture, gfxImageSurface* surface)
// host deserialization
RefPtr<TextureHost> host = CreateBackendIndependentTextureHost(descriptor, nullptr,
LayersBackend::LAYERS_NONE,
texture->GetFlags());
ASSERT_TRUE(host.get() != nullptr);
@ -192,6 +193,7 @@ void TestTextureClientYCbCr(TextureClient* client, PlanarYCbCrData& ycbcrData) {
// host deserialization
RefPtr<TextureHost> textureHost = CreateBackendIndependentTextureHost(descriptor, nullptr,
LayersBackend::LAYERS_NONE,
client->GetFlags());
RefPtr<BufferTextureHost> host = static_cast<BufferTextureHost*>(textureHost.get());

View File

@ -0,0 +1,118 @@
/* -*- 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 "RenderTextureHost.h"
#include "mozilla/gfx/Logging.h"
#include "mozilla/layers/ImageDataSerializer.h"
namespace mozilla {
using namespace gfx;
using namespace layers;
namespace wr {
RenderTextureHost::RenderTextureHost(uint8_t* aBuffer, const BufferDescriptor& aDescriptor)
: mBuffer(aBuffer)
, mDescriptor(aDescriptor)
, mLocked(false)
{
MOZ_COUNT_CTOR(RenderTextureHost);
switch (mDescriptor.type()) {
case BufferDescriptor::TYCbCrDescriptor: {
const YCbCrDescriptor& ycbcr = mDescriptor.get_YCbCrDescriptor();
mSize = ycbcr.ySize();
mFormat = gfx::SurfaceFormat::YUV;
break;
}
case BufferDescriptor::TRGBDescriptor: {
const RGBDescriptor& rgb = mDescriptor.get_RGBDescriptor();
mSize = rgb.size();
mFormat = rgb.format();
break;
}
default:
gfxCriticalError() << "Bad buffer host descriptor " << (int)mDescriptor.type();
MOZ_CRASH("GFX: Bad descriptor");
}
}
RenderTextureHost::~RenderTextureHost()
{
MOZ_COUNT_DTOR(RenderTextureHost);
}
already_AddRefed<gfx::DataSourceSurface>
RenderTextureHost::GetAsSurface()
{
RefPtr<gfx::DataSourceSurface> result;
if (mFormat == gfx::SurfaceFormat::YUV) {
result = ImageDataSerializer::DataSourceSurfaceFromYCbCrDescriptor(
GetBuffer(), mDescriptor.get_YCbCrDescriptor());
if (NS_WARN_IF(!result)) {
return nullptr;
}
} else {
result =
gfx::Factory::CreateWrappingDataSourceSurface(GetBuffer(),
ImageDataSerializer::GetRGBStride(mDescriptor.get_RGBDescriptor()),
mSize, mFormat);
}
return result.forget();
}
bool
RenderTextureHost::Lock()
{
MOZ_ASSERT(!mLocked);
// XXX temporal workaround for YUV handling
if (!mSurface) {
mSurface = GetAsSurface();
if (!mSurface) {
return false;
}
}
if (NS_WARN_IF(!mSurface->Map(DataSourceSurface::MapType::READ_WRITE, &mMap))) {
mSurface = nullptr;
return false;
}
mLocked = true;
return true;
}
void
RenderTextureHost::Unlock()
{
MOZ_ASSERT(mLocked);
mLocked = false;
if (mSurface) {
mSurface->Unmap();
}
mSurface = nullptr;
}
uint8_t*
RenderTextureHost::GetDataForRender() const
{
MOZ_ASSERT(mLocked);
MOZ_ASSERT(mSurface);
return mMap.mData;
}
size_t
RenderTextureHost::GetBufferSizeForRender() const
{
MOZ_ASSERT(mLocked);
MOZ_ASSERT(mSurface);
return mMap.mStride * mSurface->GetSize().height;
}
} // namespace wr
} // namespace mozilla

View File

@ -0,0 +1,52 @@
/* -*- 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_RENDERTEXTUREHOST_H
#define MOZILLA_GFX_RENDERTEXTUREHOST_H
#include "nsISupportsImpl.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/layers/LayersSurfaces.h"
#include "mozilla/RefPtr.h"
namespace mozilla {
namespace wr {
class RenderTextureHost
{
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(RenderTextureHost)
RenderTextureHost(uint8_t* aBuffer, const layers::BufferDescriptor& aDescriptor);
bool Lock();
void Unlock();
gfx::IntSize GetSize() const { return mSize; }
gfx::SurfaceFormat GetFormat() const { return mFormat; }
uint8_t* GetDataForRender() const;
size_t GetBufferSizeForRender() const;
protected:
~RenderTextureHost();
already_AddRefed<gfx::DataSourceSurface> GetAsSurface();
uint8_t* GetBuffer() const { return mBuffer; }
uint8_t* mBuffer;
layers::BufferDescriptor mDescriptor;
gfx::IntSize mSize;
gfx::SurfaceFormat mFormat;
RefPtr<gfx::DataSourceSurface> mSurface;
gfx::DataSourceSurface::MappedSurface mMap;
bool mLocked;
};
} // namespace wr
} // namespace mozilla
#endif // MOZILLA_GFX_RENDERTEXTUREHOST_H

View File

@ -5,11 +5,12 @@
#include "RenderThread.h"
#include "nsThreadUtils.h"
#include "mozilla/webrender/RendererOGL.h"
#include "mozilla/widget/CompositorWidget.h"
#include "mozilla/layers/CompositorThread.h"
#include "mozilla/layers/CompositorBridgeParent.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/webrender/RendererOGL.h"
#include "mozilla/webrender/RenderTextureHost.h"
#include "mozilla/widget/CompositorWidget.h"
#include "base/task.h"
namespace mozilla {
@ -19,6 +20,7 @@ static StaticRefPtr<RenderThread> sRenderThread;
RenderThread::RenderThread(base::Thread* aThread)
: mThread(aThread)
, mRenderTextureMapLock("RenderThread.mRenderTextureMapLock")
{
}
@ -194,6 +196,30 @@ RenderThread::UpdateAndRender(wr::WindowId aWindowId)
));
}
void
RenderThread::RegisterExternalImage(uint64_t aExternalImageId, RenderTextureHost* aTexture)
{
MutexAutoLock lock(mRenderTextureMapLock);
MOZ_ASSERT(!mRenderTextures.Get(aExternalImageId));
mRenderTextures.Put(aExternalImageId, aTexture);
}
void
RenderThread::UnregisterExternalImage(uint64_t aExternalImageId)
{
MutexAutoLock lock(mRenderTextureMapLock);
MOZ_ASSERT(mRenderTextures.Get(aExternalImageId).get());
mRenderTextures.Remove(aExternalImageId);
}
RenderTextureHost*
RenderThread::GetRenderTexture(uint64_t aExternalImageId)
{
MutexAutoLock lock(mRenderTextureMapLock);
MOZ_ASSERT(mRenderTextures.Get(aExternalImageId).get());
return mRenderTextures.Get(aExternalImageId).get();
}
} // namespace wr
} // namespace mozilla

View File

@ -13,6 +13,7 @@
#include "base/message_loop.h"
#include "nsISupportsImpl.h"
#include "ThreadSafeRefcountingWithMainThreadDestruction.h"
#include "mozilla/Mutex.h"
#include "mozilla/webrender/webrender_ffi.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/webrender/WebRenderTypes.h"
@ -21,6 +22,7 @@ namespace mozilla {
namespace wr {
class RendererOGL;
class RenderTextureHost;
class RenderThread;
/// Base class for an event that can be scheduled to run on the render thread.
@ -99,6 +101,13 @@ public:
/// Can only be called from the render thread.
void UpdateAndRender(wr::WindowId aWindowId);
void RegisterExternalImage(uint64_t aExternalImageId, RenderTextureHost* aTexture);
void UnregisterExternalImage(uint64_t aExternalImageId);
RenderTextureHost* GetRenderTexture(uint64_t aExternalImageId);
private:
explicit RenderThread(base::Thread* aThread);
@ -108,6 +117,9 @@ private:
base::Thread* const mThread;
std::map<wr::WindowId, UniquePtr<RendererOGL>> mRenderers;
Mutex mRenderTextureMapLock;
nsDataHashtable<nsUint64HashKey, RefPtr<RenderTextureHost> > mRenderTextures;
};
} // namespace wr

View File

@ -9,6 +9,7 @@
#include "mozilla/gfx/Logging.h"
#include "mozilla/layers/CompositorBridgeParent.h"
#include "mozilla/layers/CompositorThread.h"
#include "mozilla/webrender/RenderTextureHost.h"
#include "mozilla/widget/CompositorWidget.h"
namespace mozilla {
@ -16,11 +17,20 @@ namespace wr {
WrExternalImage LockExternalImage(void* aObj, WrExternalImageId aId)
{
return WrExternalImage { /*WrExternalImageIdType::TextureHandle, */0.0f, 0.0f, 0.0f, 0.0f, 0 };
RendererOGL* renderer = reinterpret_cast<RendererOGL*>(aObj);
RenderTextureHost* texture = renderer->GetRenderTexture(aId.id);
MOZ_ASSERT(texture);
texture->Lock();
return WrExternalImage { WrExternalImageIdType::RawData, 0.0f, 0.0f, 0.0f, 0.0f, 0,
texture->GetDataForRender(), texture->GetBufferSizeForRender() };
}
void UnlockExternalImage(void* aObj, WrExternalImageId aId)
{
RendererOGL* renderer = reinterpret_cast<RendererOGL*>(aObj);
RenderTextureHost* texture = renderer->GetRenderTexture(aId.id);
MOZ_ASSERT(texture);
texture->Unlock();
}
void ReleaseExternalImage(void* aObj, WrExternalImageId aId)
@ -120,5 +130,11 @@ RendererOGL::FlushRenderedEpochs()
return wr_renderer_flush_rendered_epochs(mWrRenderer);
}
RenderTextureHost*
RendererOGL::GetRenderTexture(uint64_t aExternalImageId)
{
return mThread->GetRenderTexture(aExternalImageId);
}
} // namespace wr
} // namespace mozilla

View File

@ -31,6 +31,8 @@ class CompositorWidget;
namespace wr {
class RenderTextureHost;
/// Owns the WebRender renderer and GL context.
///
/// There is one renderer per window, all owned by the render thread.
@ -72,6 +74,8 @@ public:
WrRenderedEpochs* FlushRenderedEpochs();
RenderTextureHost* GetRenderTexture(uint64_t aExternalImageId);
protected:
RefPtr<RenderThread> mThread;

View File

@ -249,6 +249,42 @@ WebRenderAPI::Readback(gfx::IntSize size,
task.Wait();
}
void
WebRenderAPI::WaitFlushed()
{
class WaitFlushedEvent : public RendererEvent
{
public:
explicit WaitFlushedEvent(layers::SynchronousTask* aTask)
: mTask(aTask)
{
MOZ_COUNT_CTOR(WaitFlushedEvent);
}
~WaitFlushedEvent()
{
MOZ_COUNT_DTOR(WaitFlushedEvent);
}
virtual void Run(RenderThread& aRenderThread, WindowId aWindowId) override
{
layers::AutoCompleteTask complete(mTask);
}
layers::SynchronousTask* mTask;
};
layers::SynchronousTask task("WaitFlushed");
auto event = MakeUnique<WaitFlushedEvent>(&task);
// This event will be passed from wr_backend thread to renderer thread. That
// implies that all frame data have been processed when the renderer runs this
// read-back event. Then, we could make sure this read-back event gets the
// latest result.
RunOnRenderThread(Move(event));
task.Wait();
}
void
WebRenderAPI::SetRootPipeline(PipelineId aPipeline)
{

View File

@ -22,6 +22,7 @@ class CompositorWidget;
namespace layers {
class CompositorBridgeParentBase;
class WebRenderBridgeParent;
}
namespace wr {
@ -30,8 +31,6 @@ class DisplayListBuilder;
class RendererOGL;
class RendererEvent;
class WebRenderAPI
{
NS_INLINE_DECL_REFCOUNTING(WebRenderAPI);
@ -106,6 +105,8 @@ protected:
{}
~WebRenderAPI();
// Should be used only for shutdown handling
void WaitFlushed();
WrAPI* mWrApi;
wr::WindowId mId;
@ -113,6 +114,7 @@ protected:
bool mUseANGLE;
friend class DisplayListBuilder;
friend class layers::WebRenderBridgeParent;
};
/// This is a simple C++ wrapper around WrState defined in the rust bindings.

View File

@ -9,6 +9,7 @@ with Files('**'):
EXPORTS.mozilla.webrender += [
'RendererOGL.h',
'RenderTextureHost.h',
'RenderThread.h',
'webrender_ffi.h',
'WebRenderAPI.h',
@ -17,6 +18,7 @@ EXPORTS.mozilla.webrender += [
UNIFIED_SOURCES += [
'RendererOGL.cpp',
'RenderTextureHost.cpp',
'RenderThread.cpp',
'WebRenderAPI.cpp',
]

View File

@ -491,16 +491,16 @@ pub struct WrState {
frame_builder: WebRenderFrameBuilder,
}
// TODO(Jerry): handle shmem or cpu raw buffers.
//#[repr(C)]
//enum WrExternalImageType {
// TextureHandle,
// MemOrShmem,
//}
#[repr(C)]
#[allow(dead_code)]
enum WrExternalImageType {
NativeTexture,
RawData,
}
#[repr(C)]
struct WrExternalImageStruct {
//image_type: WrExternalImageType,
image_type: WrExternalImageType,
// Texture coordinate
u0: f32,
@ -511,9 +511,9 @@ struct WrExternalImageStruct {
// external buffer handle
handle: u32,
// TODO(Jerry): handle shmem or cpu raw buffers.
//// buff: *const u8,
//// size: usize,
// handle RawData.
buff: *const u8,
size: usize,
}
type LockExternalImageCallback = fn(*mut c_void, ExternalImageId) -> WrExternalImageStruct;
@ -532,17 +532,24 @@ impl ExternalImageHandler for WrExternalImageHandler {
fn lock(&mut self, id: ExternalImageId) -> ExternalImage {
let image = (self.lock_func)(self.external_image_obj, id);
// TODO(Jerry): handle shmem or cpu raw buffers.
//match image.image_type {
// WrExternalImageType::TextureHandle =>
match image.image_type {
WrExternalImageType::NativeTexture =>
ExternalImage {
u0: image.u0,
v0: image.v0,
u1: image.u1,
v1: image.v1,
source: ExternalImageSource::NativeTexture(image.handle)
}
//}
},
WrExternalImageType::RawData =>
ExternalImage {
u0: image.u0,
v0: image.v0,
u1: image.u1,
v1: image.v1,
source: ExternalImageSource::RawData(unsafe { slice::from_raw_parts(image.buff, image.size)})
},
}
}
fn unlock(&mut self, id: ExternalImageId) {

View File

@ -23,6 +23,9 @@ struct WrType { \
bool operator<(const WrType& rhs) const { \
return mHandle < rhs.mHandle; \
} \
bool operator<=(const WrType& rhs) const { \
return mHandle <= rhs.mHandle; \
} \
}; \
// ---
@ -115,14 +118,13 @@ enum class WrImageRendering: uint32_t
Sentinel /* this must be last, for IPC serialization purposes */
};
// TODO(Jerry): handle shmem or cpu raw buffers.
//enum class WrExternalImageIdType: uint32_t
//{
// TextureHandle = 0,
// MemOrShmem = 1,
//
// Sentinel /* this must be last, for IPC serialization purposes */
//};
enum class WrExternalImageIdType: uint32_t
{
NativeTexture, // Currently, we only support gl texture handle.
RawData,
Sentinel /* this must be last, for IPC serialization purposes */
};
enum class WrMixBlendMode: uint32_t
{
@ -309,7 +311,7 @@ struct WrExternalImageId
struct WrExternalImage
{
//WrExternalImageIdType type;
WrExternalImageIdType type;
// Texture coordinate
float u0, v0;
@ -318,10 +320,9 @@ struct WrExternalImage
// external buffer handle
uint32_t handle;
// TODO(Jerry): handle shmem or cpu raw buffers.
//// shmem or memory buffer
//// uint8_t* buff;
//// size_t size;
// handle RawData.
uint8_t* buff;
size_t size;
};
typedef WrExternalImage (*LockExternalImageCallback)(void*, WrExternalImageId);