зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1317935 - Use GetCompositeUntilTime() to trigger next composition r=nical?
This commit is contained in:
Родитель
2deb064663
Коммит
a450a2754f
|
@ -135,6 +135,7 @@ class CompositorD3D11;
|
|||
class BasicCompositor;
|
||||
class TextureHost;
|
||||
class TextureReadLock;
|
||||
class WebRenderCompositorOGL;
|
||||
|
||||
enum SurfaceInitMode
|
||||
{
|
||||
|
@ -466,6 +467,7 @@ public:
|
|||
virtual CompositorD3D9* AsCompositorD3D9() { return nullptr; }
|
||||
virtual CompositorD3D11* AsCompositorD3D11() { return nullptr; }
|
||||
virtual BasicCompositor* AsBasicCompositor() { return nullptr; }
|
||||
virtual WebRenderCompositorOGL* AsWebRenderCompositorOGL() { return nullptr; }
|
||||
|
||||
/**
|
||||
* Each Compositor has a unique ID.
|
||||
|
@ -546,7 +548,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
void CompositeUntil(TimeStamp aTimeStamp) {
|
||||
virtual void CompositeUntil(TimeStamp aTimeStamp) {
|
||||
if (mCompositeUntilTime.IsNull() ||
|
||||
mCompositeUntilTime < aTimeStamp) {
|
||||
mCompositeUntilTime = aTimeStamp;
|
||||
|
|
|
@ -239,6 +239,8 @@ public:
|
|||
/// is is destroyed.
|
||||
virtual void CleanupResources() {}
|
||||
|
||||
virtual void BindTextureSource() {}
|
||||
|
||||
protected:
|
||||
TextureInfo mTextureInfo;
|
||||
uint64_t mAsyncID;
|
||||
|
|
|
@ -433,6 +433,31 @@ ImageHost::Composite(LayerComposite* aLayer,
|
|||
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
|
||||
ImageHost::SetCompositor(Compositor* aCompositor)
|
||||
{
|
||||
|
|
|
@ -89,6 +89,8 @@ public:
|
|||
|
||||
virtual void CleanupResources() override;
|
||||
|
||||
virtual void BindTextureSource() override;
|
||||
|
||||
int32_t GetFrameID()
|
||||
{
|
||||
const TimedImage* img = ChooseImage();
|
||||
|
|
|
@ -1552,7 +1552,7 @@ CompositorBridgeParent::AllocPWebRenderBridgeParent(const uint64_t& aPipelineId)
|
|||
|
||||
RefPtr<gl::GLContext> glc(gl::GLContextProvider::CreateForCompositorWidget(mWidget, true));
|
||||
RefPtr<Compositor> compositor = new WebRenderCompositorOGL(glc.get());
|
||||
WebRenderBridgeParent* parent = new WebRenderBridgeParent(nullptr, aPipelineId,
|
||||
WebRenderBridgeParent* parent = new WebRenderBridgeParent(aPipelineId,
|
||||
mWidget, glc.get(), nullptr, compositor.get());
|
||||
parent->AddRef(); // IPDL reference
|
||||
MonitorAutoLock lock(*sIndirectLayerTreesLock);
|
||||
|
|
|
@ -212,7 +212,7 @@ CrossProcessCompositorBridgeParent::AllocPWebRenderBridgeParent(const uint64_t&
|
|||
WebRenderBridgeParent* root = sIndirectLayerTrees[cbp->RootLayerTreeId()].mWRBridge.get();
|
||||
|
||||
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
|
||||
sIndirectLayerTrees[aPipelineId].mWRBridge = parent;
|
||||
|
||||
|
|
|
@ -35,6 +35,8 @@ parent:
|
|||
sync DPSyncEnd(WebRenderCommand[] commands);
|
||||
sync DPGetSnapshot(uint32_t aWidth, uint32_t aHeight)
|
||||
returns (uint8_t[] aOutImageSnapshot);
|
||||
async AddExternalImageId(uint64_t aImageId, uint64_t aAsyncContainerId);
|
||||
async RemoveExternalImageId(uint64_t aImageId);
|
||||
|
||||
async __delete__();
|
||||
};
|
||||
|
|
|
@ -51,5 +51,29 @@ WebRenderBridgeChild::DPEnd(bool aIsSync)
|
|||
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 mozilla
|
||||
|
|
|
@ -30,6 +30,9 @@ public:
|
|||
|
||||
bool DPBegin(uint32_t aWidth, uint32_t aHeight);
|
||||
void DPEnd(bool aIsSync = false);
|
||||
|
||||
uint64_t AllocExternalImageId(uint64_t aAsyncContainerID);
|
||||
void DeallocExternalImageId(uint64_t aImageId);
|
||||
protected:
|
||||
~WebRenderBridgeChild() {}
|
||||
|
||||
|
|
|
@ -6,23 +6,23 @@
|
|||
|
||||
#include "mozilla/layers/WebRenderBridgeParent.h"
|
||||
|
||||
#include "CompositableHost.h"
|
||||
#include "GLContext.h"
|
||||
#include "GLContextProvider.h"
|
||||
#include "mozilla/layers/Compositor.h"
|
||||
#include "mozilla/layers/CompositorVsyncScheduler.h"
|
||||
#include "mozilla/widget/CompositorWidget.h"
|
||||
#include "mozilla/layers/WebRenderCompositorOGL.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
WebRenderBridgeParent::WebRenderBridgeParent(WebRenderBridgeParent* aParent,
|
||||
const uint64_t& aPipelineId,
|
||||
WebRenderBridgeParent::WebRenderBridgeParent(const uint64_t& aPipelineId,
|
||||
widget::CompositorWidget* aWidget,
|
||||
gl::GLContext* aGlContext,
|
||||
wrwindowstate* aWrWindowState,
|
||||
layers::Compositor* aCompositor)
|
||||
: mParent(aParent)
|
||||
, mPipelineId(aPipelineId)
|
||||
: mPipelineId(aPipelineId)
|
||||
, mWidget(aWidget)
|
||||
, mWRState(nullptr)
|
||||
, mGLContext(aGlContext)
|
||||
|
@ -40,6 +40,7 @@ WebRenderBridgeParent::WebRenderBridgeParent(WebRenderBridgeParent* aParent,
|
|||
}
|
||||
if (mWidget) {
|
||||
mCompositorScheduler = new CompositorVsyncScheduler(this, mWidget);
|
||||
mCompositor->AsWebRenderCompositorOGL()->SetVsyncScheduler(mCompositorScheduler);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -186,9 +187,48 @@ WebRenderBridgeParent::RecvDPGetSnapshot(const uint32_t& aWidth,
|
|||
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
|
||||
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();
|
||||
}
|
||||
|
||||
|
@ -204,6 +244,7 @@ WebRenderBridgeParent::CompositeToTarget(gfx::DrawTarget* aTarget, const gfx::In
|
|||
}
|
||||
|
||||
mCompositor->SetCompositionTime(TimeStamp::Now());
|
||||
mCompositor->AsWebRenderCompositorOGL()->UpdateExternalImages();
|
||||
|
||||
MOZ_ASSERT(mWRState);
|
||||
mozilla::widget::WidgetRenderingContext widgetContext;
|
||||
|
@ -235,11 +276,7 @@ WebRenderBridgeParent::DeleteOldImages()
|
|||
void
|
||||
WebRenderBridgeParent::ScheduleComposition()
|
||||
{
|
||||
if (mCompositorScheduler) {
|
||||
mCompositorScheduler->ScheduleComposition();
|
||||
} else if (mParent) {
|
||||
mParent->ScheduleComposition();
|
||||
}
|
||||
mCompositor->AsWebRenderCompositorOGL()->ScheduleComposition();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -259,7 +296,6 @@ WebRenderBridgeParent::ClearResources()
|
|||
mCompositorScheduler = nullptr;
|
||||
}
|
||||
mGLContext = nullptr;
|
||||
mParent = nullptr;
|
||||
}
|
||||
|
||||
} // namespace layers
|
||||
|
|
|
@ -33,8 +33,7 @@ class WebRenderBridgeParent final : public PWebRenderBridgeParent
|
|||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(WebRenderBridgeParent)
|
||||
|
||||
public:
|
||||
WebRenderBridgeParent(WebRenderBridgeParent* aParent,
|
||||
const uint64_t& aPipelineId,
|
||||
WebRenderBridgeParent(const uint64_t& aPipelineId,
|
||||
widget::CompositorWidget* aWidget,
|
||||
gl::GLContext* aGlContext,
|
||||
wrwindowstate* aWrWindowState,
|
||||
|
@ -68,6 +67,10 @@ public:
|
|||
const uint32_t& aHeight,
|
||||
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;
|
||||
|
||||
// CompositorVsyncSchedulerOwner
|
||||
|
@ -83,8 +86,6 @@ protected:
|
|||
void ClearResources();
|
||||
|
||||
private:
|
||||
// XXX remove mParent in Bug 1317935
|
||||
RefPtr<WebRenderBridgeParent> mParent;
|
||||
uint64_t mPipelineId;
|
||||
RefPtr<widget::CompositorWidget> mWidget;
|
||||
wrstate* mWRState;
|
||||
|
@ -93,6 +94,7 @@ private:
|
|||
RefPtr<layers::Compositor> mCompositor;
|
||||
RefPtr<CompositorVsyncScheduler> mCompositorScheduler;
|
||||
std::vector<WRImageKey> mKeysToDelete;
|
||||
nsDataHashtable<nsUint64HashKey, uint64_t> mExternalImageIds;
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
|
|
|
@ -5,8 +5,10 @@
|
|||
|
||||
#include "WebRenderCompositorOGL.h"
|
||||
|
||||
#include "CompositableHost.h"
|
||||
#include "GLContext.h" // for GLContext
|
||||
#include "GLUploadHelpers.h"
|
||||
#include "mozilla/layers/CompositorVsyncScheduler.h"
|
||||
#include "mozilla/layers/TextureHost.h" // for TextureSource, etc
|
||||
#include "mozilla/layers/TextureHostOGL.h" // for TextureSourceOGL, etc
|
||||
|
||||
|
@ -35,6 +37,9 @@ WebRenderCompositorOGL::Destroy()
|
|||
{
|
||||
Compositor::Destroy();
|
||||
|
||||
mCompositableHosts.Clear();
|
||||
mCompositorScheduler = nullptr;
|
||||
|
||||
if (!mDestroyed) {
|
||||
mDestroyed = true;
|
||||
mGLContext = nullptr;;
|
||||
|
@ -80,5 +85,53 @@ WebRenderCompositorOGL::MakeCurrent(MakeCurrentFlags aFlags) {
|
|||
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 mozilla
|
||||
|
|
|
@ -9,10 +9,14 @@
|
|||
#include "GLContextTypes.h" // for GLContext, etc
|
||||
#include "GLDefs.h" // for GLuint, LOCAL_GL_TEXTURE_2D, etc
|
||||
#include "mozilla/layers/Compositor.h" // for SurfaceInitMode, Compositor, etc
|
||||
#include "nsDataHashtable.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
class CompositableHost;
|
||||
class CompositorVsyncScheduler;
|
||||
|
||||
class WebRenderCompositorOGL final : public Compositor
|
||||
{
|
||||
typedef mozilla::gl::GLContext GLContext;
|
||||
|
@ -24,6 +28,8 @@ protected:
|
|||
virtual ~WebRenderCompositorOGL();
|
||||
|
||||
public:
|
||||
virtual WebRenderCompositorOGL* AsWebRenderCompositorOGL() override { return this; }
|
||||
|
||||
virtual already_AddRefed<DataTextureSource>
|
||||
CreateDataTextureSource(TextureFlags aFlags = TextureFlags::NO_FLAGS) override;
|
||||
|
||||
|
@ -106,10 +112,21 @@ public:
|
|||
|
||||
virtual bool IsValid() const override { return true; }
|
||||
|
||||
virtual void CompositeUntil(TimeStamp aTimeStamp) override;
|
||||
|
||||
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:
|
||||
RefPtr<GLContext> mGLContext;
|
||||
RefPtr<CompositorVsyncScheduler> mCompositorScheduler;
|
||||
// Holds CompositableHosts that are bound to external image ids.
|
||||
nsDataHashtable<nsUint64HashKey, RefPtr<CompositableHost> > mCompositableHosts;
|
||||
|
||||
bool mDestroyed;
|
||||
};
|
||||
|
|
|
@ -13,6 +13,14 @@ namespace layers {
|
|||
|
||||
using namespace gfx;
|
||||
|
||||
WebRenderImageLayer::~WebRenderImageLayer()
|
||||
{
|
||||
MOZ_COUNT_DTOR(WebRenderImageLayer);
|
||||
if (mImageId) {
|
||||
WRBridge()->DeallocExternalImageId(mImageId);
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<gfx::SourceSurface>
|
||||
WebRenderImageLayer::GetAsSourceSurface()
|
||||
{
|
||||
|
@ -31,6 +39,12 @@ WebRenderImageLayer::GetAsSourceSurface()
|
|||
void
|
||||
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();
|
||||
if (!surface)
|
||||
return;
|
||||
|
|
|
@ -17,16 +17,14 @@ class WebRenderImageLayer : public WebRenderLayer,
|
|||
public:
|
||||
explicit WebRenderImageLayer(WebRenderLayerManager* aLayerManager)
|
||||
: ImageLayer(aLayerManager, static_cast<WebRenderLayer*>(this))
|
||||
, mImageId(0)
|
||||
{
|
||||
MOZ_COUNT_CTOR(WebRenderImageLayer);
|
||||
}
|
||||
|
||||
virtual already_AddRefed<gfx::SourceSurface> GetAsSourceSurface() override;
|
||||
protected:
|
||||
virtual ~WebRenderImageLayer()
|
||||
{
|
||||
MOZ_COUNT_DTOR(WebRenderImageLayer);
|
||||
}
|
||||
virtual ~WebRenderImageLayer();
|
||||
|
||||
WebRenderLayerManager* Manager()
|
||||
{
|
||||
|
@ -36,6 +34,9 @@ protected:
|
|||
public:
|
||||
Layer* GetLayer() override { return this; }
|
||||
void RenderLayer() override;
|
||||
|
||||
protected:
|
||||
uint64_t mImageId;
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
|
|
Загрузка…
Ссылка в новой задаче