Bug 1317935 - Use GetCompositeUntilTime() to trigger next composition r=nical?

This commit is contained in:
sotaro 2016-11-24 15:48:01 +09:00
Родитель 2deb064663
Коммит a450a2754f
15 изменённых файлов: 204 добавлений и 21 удалений

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

@ -135,6 +135,7 @@ class CompositorD3D11;
class BasicCompositor; class BasicCompositor;
class TextureHost; class TextureHost;
class TextureReadLock; class TextureReadLock;
class WebRenderCompositorOGL;
enum SurfaceInitMode enum SurfaceInitMode
{ {
@ -466,6 +467,7 @@ public:
virtual CompositorD3D9* AsCompositorD3D9() { return nullptr; } virtual CompositorD3D9* AsCompositorD3D9() { return nullptr; }
virtual CompositorD3D11* AsCompositorD3D11() { return nullptr; } virtual CompositorD3D11* AsCompositorD3D11() { return nullptr; }
virtual BasicCompositor* AsBasicCompositor() { return nullptr; } virtual BasicCompositor* AsBasicCompositor() { return nullptr; }
virtual WebRenderCompositorOGL* AsWebRenderCompositorOGL() { return nullptr; }
/** /**
* Each Compositor has a unique ID. * Each Compositor has a unique ID.
@ -546,7 +548,7 @@ public:
} }
} }
void CompositeUntil(TimeStamp aTimeStamp) { virtual void CompositeUntil(TimeStamp aTimeStamp) {
if (mCompositeUntilTime.IsNull() || if (mCompositeUntilTime.IsNull() ||
mCompositeUntilTime < aTimeStamp) { mCompositeUntilTime < aTimeStamp) {
mCompositeUntilTime = aTimeStamp; mCompositeUntilTime = aTimeStamp;

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

@ -239,6 +239,8 @@ public:
/// is is destroyed. /// is is destroyed.
virtual void CleanupResources() {} virtual void CleanupResources() {}
virtual void BindTextureSource() {}
protected: protected:
TextureInfo mTextureInfo; TextureInfo mTextureInfo;
uint64_t mAsyncID; uint64_t mAsyncID;

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

@ -433,6 +433,31 @@ ImageHost::Composite(LayerComposite* aLayer,
mBias); mBias);
} }
void
ImageHost::BindTextureSource()
{
int imageIndex = ChooseImageIndex();
if (imageIndex < 0) {
return;
}
if (uint32_t(imageIndex) + 1 < mImages.Length()) {
GetCompositor()->CompositeUntil(mImages[imageIndex + 1].mTimeStamp + TimeDuration::FromMilliseconds(BIAS_TIME_MS));
}
TimedImage* img = &mImages[imageIndex];
img->mTextureHost->SetCompositor(GetCompositor());
SetCurrentTextureHost(img->mTextureHost);
// XXX Add TextureSource binding
mBias = UpdateBias(
GetCompositor()->GetCompositionTime(), mImages[imageIndex].mTimeStamp,
uint32_t(imageIndex + 1) < mImages.Length() ?
mImages[imageIndex + 1].mTimeStamp : TimeStamp(),
mBias);
}
void void
ImageHost::SetCompositor(Compositor* aCompositor) ImageHost::SetCompositor(Compositor* aCompositor)
{ {

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

@ -89,6 +89,8 @@ public:
virtual void CleanupResources() override; virtual void CleanupResources() override;
virtual void BindTextureSource() override;
int32_t GetFrameID() int32_t GetFrameID()
{ {
const TimedImage* img = ChooseImage(); const TimedImage* img = ChooseImage();

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

@ -1552,7 +1552,7 @@ CompositorBridgeParent::AllocPWebRenderBridgeParent(const uint64_t& aPipelineId)
RefPtr<gl::GLContext> glc(gl::GLContextProvider::CreateForCompositorWidget(mWidget, true)); RefPtr<gl::GLContext> glc(gl::GLContextProvider::CreateForCompositorWidget(mWidget, true));
RefPtr<Compositor> compositor = new WebRenderCompositorOGL(glc.get()); RefPtr<Compositor> compositor = new WebRenderCompositorOGL(glc.get());
WebRenderBridgeParent* parent = new WebRenderBridgeParent(nullptr, aPipelineId, WebRenderBridgeParent* parent = new WebRenderBridgeParent(aPipelineId,
mWidget, glc.get(), nullptr, compositor.get()); mWidget, glc.get(), nullptr, compositor.get());
parent->AddRef(); // IPDL reference parent->AddRef(); // IPDL reference
MonitorAutoLock lock(*sIndirectLayerTreesLock); MonitorAutoLock lock(*sIndirectLayerTreesLock);

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

@ -212,7 +212,7 @@ CrossProcessCompositorBridgeParent::AllocPWebRenderBridgeParent(const uint64_t&
WebRenderBridgeParent* root = sIndirectLayerTrees[cbp->RootLayerTreeId()].mWRBridge.get(); WebRenderBridgeParent* root = sIndirectLayerTrees[cbp->RootLayerTreeId()].mWRBridge.get();
WebRenderBridgeParent* parent = new WebRenderBridgeParent( WebRenderBridgeParent* parent = new WebRenderBridgeParent(
root, aPipelineId, nullptr, root->GLContext(), root->WindowState(), root->Compositor()); aPipelineId, nullptr, root->GLContext(), root->WindowState(), root->Compositor());
parent->AddRef(); // IPDL reference parent->AddRef(); // IPDL reference
sIndirectLayerTrees[aPipelineId].mWRBridge = parent; sIndirectLayerTrees[aPipelineId].mWRBridge = parent;

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

@ -35,6 +35,8 @@ parent:
sync DPSyncEnd(WebRenderCommand[] commands); sync DPSyncEnd(WebRenderCommand[] commands);
sync DPGetSnapshot(uint32_t aWidth, uint32_t aHeight) sync DPGetSnapshot(uint32_t aWidth, uint32_t aHeight)
returns (uint8_t[] aOutImageSnapshot); returns (uint8_t[] aOutImageSnapshot);
async AddExternalImageId(uint64_t aImageId, uint64_t aAsyncContainerId);
async RemoveExternalImageId(uint64_t aImageId);
async __delete__(); async __delete__();
}; };

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

@ -51,5 +51,29 @@ WebRenderBridgeChild::DPEnd(bool aIsSync)
mIsInTransaction = false; mIsInTransaction = false;
} }
uint64_t
WebRenderBridgeChild::AllocExternalImageId(uint64_t aAsyncContainerID)
{
static uint32_t sNextID = 1;
++sNextID;
MOZ_RELEASE_ASSERT(sNextID != UINT32_MAX);
// XXX replace external image id allocation with webrender's id allocation.
// Use proc id as IdNamespace for now.
uint32_t procId = static_cast<uint32_t>(base::GetCurrentProcId());
uint64_t imageId = procId;
imageId = imageId << 32 | sNextID;
SendAddExternalImageId(imageId, aAsyncContainerID);
return imageId;
}
void
WebRenderBridgeChild::DeallocExternalImageId(uint64_t aImageId)
{
MOZ_ASSERT(aImageId);
SendRemoveExternalImageId(aImageId);
}
} // namespace layers } // namespace layers
} // namespace mozilla } // namespace mozilla

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

@ -30,6 +30,9 @@ public:
bool DPBegin(uint32_t aWidth, uint32_t aHeight); bool DPBegin(uint32_t aWidth, uint32_t aHeight);
void DPEnd(bool aIsSync = false); void DPEnd(bool aIsSync = false);
uint64_t AllocExternalImageId(uint64_t aAsyncContainerID);
void DeallocExternalImageId(uint64_t aImageId);
protected: protected:
~WebRenderBridgeChild() {} ~WebRenderBridgeChild() {}

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

@ -6,23 +6,23 @@
#include "mozilla/layers/WebRenderBridgeParent.h" #include "mozilla/layers/WebRenderBridgeParent.h"
#include "CompositableHost.h"
#include "GLContext.h" #include "GLContext.h"
#include "GLContextProvider.h" #include "GLContextProvider.h"
#include "mozilla/layers/Compositor.h" #include "mozilla/layers/Compositor.h"
#include "mozilla/layers/CompositorVsyncScheduler.h" #include "mozilla/layers/CompositorVsyncScheduler.h"
#include "mozilla/widget/CompositorWidget.h" #include "mozilla/widget/CompositorWidget.h"
#include "mozilla/layers/WebRenderCompositorOGL.h"
namespace mozilla { namespace mozilla {
namespace layers { namespace layers {
WebRenderBridgeParent::WebRenderBridgeParent(WebRenderBridgeParent* aParent, WebRenderBridgeParent::WebRenderBridgeParent(const uint64_t& aPipelineId,
const uint64_t& aPipelineId,
widget::CompositorWidget* aWidget, widget::CompositorWidget* aWidget,
gl::GLContext* aGlContext, gl::GLContext* aGlContext,
wrwindowstate* aWrWindowState, wrwindowstate* aWrWindowState,
layers::Compositor* aCompositor) layers::Compositor* aCompositor)
: mParent(aParent) : mPipelineId(aPipelineId)
, mPipelineId(aPipelineId)
, mWidget(aWidget) , mWidget(aWidget)
, mWRState(nullptr) , mWRState(nullptr)
, mGLContext(aGlContext) , mGLContext(aGlContext)
@ -40,6 +40,7 @@ WebRenderBridgeParent::WebRenderBridgeParent(WebRenderBridgeParent* aParent,
} }
if (mWidget) { if (mWidget) {
mCompositorScheduler = new CompositorVsyncScheduler(this, mWidget); mCompositorScheduler = new CompositorVsyncScheduler(this, mWidget);
mCompositor->AsWebRenderCompositorOGL()->SetVsyncScheduler(mCompositorScheduler);
} }
} }
@ -186,9 +187,48 @@ WebRenderBridgeParent::RecvDPGetSnapshot(const uint32_t& aWidth,
return IPC_OK(); return IPC_OK();
} }
mozilla::ipc::IPCResult
WebRenderBridgeParent::RecvAddExternalImageId(const uint64_t& aImageId,
const uint64_t& aAsyncContainerId)
{
MOZ_ASSERT(!mExternalImageIds.Get(aImageId));
PCompositableParent* compositableParent = CompositableMap::Get(aAsyncContainerId);
if (!compositableParent) {
NS_ERROR("CompositableParent not found in the map");
return IPC_OK();
}
CompositableHost* host = CompositableHost::FromIPDLActor(compositableParent);
if (host->GetType() != CompositableType::IMAGE) {
NS_ERROR("Incompatible CompositableHost");
return IPC_OK();
}
host->SetCompositor(mCompositor);
mCompositor->AsWebRenderCompositorOGL()->AddExternalImageId(aImageId, host);
mExternalImageIds.Put(aImageId, aImageId);
return IPC_OK();
}
mozilla::ipc::IPCResult
WebRenderBridgeParent::RecvRemoveExternalImageId(const uint64_t& aImageId)
{
MOZ_ASSERT(mExternalImageIds.Get(aImageId));
mExternalImageIds.Remove(aImageId);
mCompositor->AsWebRenderCompositorOGL()->RemoveExternalImageId(aImageId);
return IPC_OK();
}
void void
WebRenderBridgeParent::ActorDestroy(ActorDestroyReason aWhy) WebRenderBridgeParent::ActorDestroy(ActorDestroyReason aWhy)
{ {
for (auto iter = mExternalImageIds.Iter(); !iter.Done(); iter.Next()) {
uint64_t externalImageId = iter.Data();
mCompositor->AsWebRenderCompositorOGL()->RemoveExternalImageId(externalImageId);
}
mExternalImageIds.Clear();
ClearResources(); ClearResources();
} }
@ -204,6 +244,7 @@ WebRenderBridgeParent::CompositeToTarget(gfx::DrawTarget* aTarget, const gfx::In
} }
mCompositor->SetCompositionTime(TimeStamp::Now()); mCompositor->SetCompositionTime(TimeStamp::Now());
mCompositor->AsWebRenderCompositorOGL()->UpdateExternalImages();
MOZ_ASSERT(mWRState); MOZ_ASSERT(mWRState);
mozilla::widget::WidgetRenderingContext widgetContext; mozilla::widget::WidgetRenderingContext widgetContext;
@ -235,11 +276,7 @@ WebRenderBridgeParent::DeleteOldImages()
void void
WebRenderBridgeParent::ScheduleComposition() WebRenderBridgeParent::ScheduleComposition()
{ {
if (mCompositorScheduler) { mCompositor->AsWebRenderCompositorOGL()->ScheduleComposition();
mCompositorScheduler->ScheduleComposition();
} else if (mParent) {
mParent->ScheduleComposition();
}
} }
void void
@ -259,7 +296,6 @@ WebRenderBridgeParent::ClearResources()
mCompositorScheduler = nullptr; mCompositorScheduler = nullptr;
} }
mGLContext = nullptr; mGLContext = nullptr;
mParent = nullptr;
} }
} // namespace layers } // namespace layers

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

@ -33,8 +33,7 @@ class WebRenderBridgeParent final : public PWebRenderBridgeParent
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(WebRenderBridgeParent) NS_INLINE_DECL_THREADSAFE_REFCOUNTING(WebRenderBridgeParent)
public: public:
WebRenderBridgeParent(WebRenderBridgeParent* aParent, WebRenderBridgeParent(const uint64_t& aPipelineId,
const uint64_t& aPipelineId,
widget::CompositorWidget* aWidget, widget::CompositorWidget* aWidget,
gl::GLContext* aGlContext, gl::GLContext* aGlContext,
wrwindowstate* aWrWindowState, wrwindowstate* aWrWindowState,
@ -68,6 +67,10 @@ public:
const uint32_t& aHeight, const uint32_t& aHeight,
InfallibleTArray<uint8_t>* aOutImageSnapshot) override; InfallibleTArray<uint8_t>* aOutImageSnapshot) override;
mozilla::ipc::IPCResult RecvAddExternalImageId(const uint64_t& aImageId,
const uint64_t& aAsyncContainerId) override;
mozilla::ipc::IPCResult RecvRemoveExternalImageId(const uint64_t& aImageId) override;
void ActorDestroy(ActorDestroyReason aWhy) override; void ActorDestroy(ActorDestroyReason aWhy) override;
// CompositorVsyncSchedulerOwner // CompositorVsyncSchedulerOwner
@ -83,8 +86,6 @@ protected:
void ClearResources(); void ClearResources();
private: private:
// XXX remove mParent in Bug 1317935
RefPtr<WebRenderBridgeParent> mParent;
uint64_t mPipelineId; uint64_t mPipelineId;
RefPtr<widget::CompositorWidget> mWidget; RefPtr<widget::CompositorWidget> mWidget;
wrstate* mWRState; wrstate* mWRState;
@ -93,6 +94,7 @@ private:
RefPtr<layers::Compositor> mCompositor; RefPtr<layers::Compositor> mCompositor;
RefPtr<CompositorVsyncScheduler> mCompositorScheduler; RefPtr<CompositorVsyncScheduler> mCompositorScheduler;
std::vector<WRImageKey> mKeysToDelete; std::vector<WRImageKey> mKeysToDelete;
nsDataHashtable<nsUint64HashKey, uint64_t> mExternalImageIds;
}; };
} // namespace layers } // namespace layers

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

@ -5,8 +5,10 @@
#include "WebRenderCompositorOGL.h" #include "WebRenderCompositorOGL.h"
#include "CompositableHost.h"
#include "GLContext.h" // for GLContext #include "GLContext.h" // for GLContext
#include "GLUploadHelpers.h" #include "GLUploadHelpers.h"
#include "mozilla/layers/CompositorVsyncScheduler.h"
#include "mozilla/layers/TextureHost.h" // for TextureSource, etc #include "mozilla/layers/TextureHost.h" // for TextureSource, etc
#include "mozilla/layers/TextureHostOGL.h" // for TextureSourceOGL, etc #include "mozilla/layers/TextureHostOGL.h" // for TextureSourceOGL, etc
@ -35,6 +37,9 @@ WebRenderCompositorOGL::Destroy()
{ {
Compositor::Destroy(); Compositor::Destroy();
mCompositableHosts.Clear();
mCompositorScheduler = nullptr;
if (!mDestroyed) { if (!mDestroyed) {
mDestroyed = true; mDestroyed = true;
mGLContext = nullptr;; mGLContext = nullptr;;
@ -80,5 +85,53 @@ WebRenderCompositorOGL::MakeCurrent(MakeCurrentFlags aFlags) {
mGLContext->MakeCurrent(aFlags & ForceMakeCurrent); mGLContext->MakeCurrent(aFlags & ForceMakeCurrent);
} }
void
WebRenderCompositorOGL::CompositeUntil(TimeStamp aTimeStamp)
{
Compositor::CompositeUntil(aTimeStamp);
// We're not really taking advantage of the stored composite-again-time here.
// We might be able to skip the next few composites altogether. However,
// that's a bit complex to implement and we'll get most of the advantage
// by skipping compositing when we detect there's nothing invalid. This is why
// we do "composite until" rather than "composite again at".
ScheduleComposition();
}
void
WebRenderCompositorOGL::AddExternalImageId(uint64_t aExternalImageId, CompositableHost* aHost)
{
MOZ_ASSERT(!mCompositableHosts.Get(aExternalImageId));
mCompositableHosts.Put(aExternalImageId, aHost);
}
void
WebRenderCompositorOGL::RemoveExternalImageId(uint64_t aExternalImageId)
{
MOZ_ASSERT(mCompositableHosts.Get(aExternalImageId));
mCompositableHosts.Remove(aExternalImageId);
}
void
WebRenderCompositorOGL::UpdateExternalImages()
{
for (auto iter = mCompositableHosts.Iter(); !iter.Done(); iter.Next()) {
RefPtr<CompositableHost>& host = iter.Data();
// XXX Change to correct TextrueSource handling here.
host->BindTextureSource();
}
}
void
WebRenderCompositorOGL::ScheduleComposition()
{
mCompositorScheduler->ScheduleComposition();
}
void
WebRenderCompositorOGL::SetVsyncScheduler(CompositorVsyncScheduler* aScheduler)
{
mCompositorScheduler = aScheduler;
}
} // namespace layers } // namespace layers
} // namespace mozilla } // namespace mozilla

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

@ -9,10 +9,14 @@
#include "GLContextTypes.h" // for GLContext, etc #include "GLContextTypes.h" // for GLContext, etc
#include "GLDefs.h" // for GLuint, LOCAL_GL_TEXTURE_2D, etc #include "GLDefs.h" // for GLuint, LOCAL_GL_TEXTURE_2D, etc
#include "mozilla/layers/Compositor.h" // for SurfaceInitMode, Compositor, etc #include "mozilla/layers/Compositor.h" // for SurfaceInitMode, Compositor, etc
#include "nsDataHashtable.h"
namespace mozilla { namespace mozilla {
namespace layers { namespace layers {
class CompositableHost;
class CompositorVsyncScheduler;
class WebRenderCompositorOGL final : public Compositor class WebRenderCompositorOGL final : public Compositor
{ {
typedef mozilla::gl::GLContext GLContext; typedef mozilla::gl::GLContext GLContext;
@ -24,6 +28,8 @@ protected:
virtual ~WebRenderCompositorOGL(); virtual ~WebRenderCompositorOGL();
public: public:
virtual WebRenderCompositorOGL* AsWebRenderCompositorOGL() override { return this; }
virtual already_AddRefed<DataTextureSource> virtual already_AddRefed<DataTextureSource>
CreateDataTextureSource(TextureFlags aFlags = TextureFlags::NO_FLAGS) override; CreateDataTextureSource(TextureFlags aFlags = TextureFlags::NO_FLAGS) override;
@ -106,10 +112,21 @@ public:
virtual bool IsValid() const override { return true; } virtual bool IsValid() const override { return true; }
virtual void CompositeUntil(TimeStamp aTimeStamp) override;
GLContext* gl() const { return mGLContext; } GLContext* gl() const { return mGLContext; }
void AddExternalImageId(uint64_t aExternalImageId, CompositableHost* aHost);
void RemoveExternalImageId(uint64_t aExternalImageId);
void UpdateExternalImages();
void ScheduleComposition();
void SetVsyncScheduler(CompositorVsyncScheduler* aScheduler);
private: private:
RefPtr<GLContext> mGLContext; RefPtr<GLContext> mGLContext;
RefPtr<CompositorVsyncScheduler> mCompositorScheduler;
// Holds CompositableHosts that are bound to external image ids.
nsDataHashtable<nsUint64HashKey, RefPtr<CompositableHost> > mCompositableHosts;
bool mDestroyed; bool mDestroyed;
}; };

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

@ -13,6 +13,14 @@ namespace layers {
using namespace gfx; using namespace gfx;
WebRenderImageLayer::~WebRenderImageLayer()
{
MOZ_COUNT_DTOR(WebRenderImageLayer);
if (mImageId) {
WRBridge()->DeallocExternalImageId(mImageId);
}
}
already_AddRefed<gfx::SourceSurface> already_AddRefed<gfx::SourceSurface>
WebRenderImageLayer::GetAsSourceSurface() WebRenderImageLayer::GetAsSourceSurface()
{ {
@ -31,6 +39,12 @@ WebRenderImageLayer::GetAsSourceSurface()
void void
WebRenderImageLayer::RenderLayer() WebRenderImageLayer::RenderLayer()
{ {
// XXX update async ImageContainer rendering path
if (mContainer->IsAsync() && !mImageId) {
mImageId = WRBridge()->AllocExternalImageId(mContainer->GetAsyncContainerID());
MOZ_ASSERT(mImageId);
}
RefPtr<gfx::SourceSurface> surface = GetAsSourceSurface(); RefPtr<gfx::SourceSurface> surface = GetAsSourceSurface();
if (!surface) if (!surface)
return; return;

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

@ -17,16 +17,14 @@ class WebRenderImageLayer : public WebRenderLayer,
public: public:
explicit WebRenderImageLayer(WebRenderLayerManager* aLayerManager) explicit WebRenderImageLayer(WebRenderLayerManager* aLayerManager)
: ImageLayer(aLayerManager, static_cast<WebRenderLayer*>(this)) : ImageLayer(aLayerManager, static_cast<WebRenderLayer*>(this))
, mImageId(0)
{ {
MOZ_COUNT_CTOR(WebRenderImageLayer); MOZ_COUNT_CTOR(WebRenderImageLayer);
} }
virtual already_AddRefed<gfx::SourceSurface> GetAsSourceSurface() override; virtual already_AddRefed<gfx::SourceSurface> GetAsSourceSurface() override;
protected: protected:
virtual ~WebRenderImageLayer() virtual ~WebRenderImageLayer();
{
MOZ_COUNT_DTOR(WebRenderImageLayer);
}
WebRenderLayerManager* Manager() WebRenderLayerManager* Manager()
{ {
@ -36,6 +34,9 @@ protected:
public: public:
Layer* GetLayer() override { return this; } Layer* GetLayer() override { return this; }
void RenderLayer() override; void RenderLayer() override;
protected:
uint64_t mImageId;
}; };
} // namespace layers } // namespace layers