зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-inbound to mozilla-central a=merge
This commit is contained in:
Коммит
7f7c353e96
|
@ -544,7 +544,7 @@ AsyncImagePipelineManager::HoldExternalImage(const wr::PipelineId& aPipelineId,
|
|||
}
|
||||
|
||||
void
|
||||
AsyncImagePipelineManager::NotifyPipelinesUpdated(wr::WrPipelineInfo aInfo, bool aRender)
|
||||
AsyncImagePipelineManager::NotifyPipelinesUpdated(const wr::WrPipelineInfo& aInfo, bool aRender)
|
||||
{
|
||||
// This is called on the render thread, so we just stash the data into
|
||||
// UpdatesQueue and process it later on the compositor thread.
|
||||
|
|
|
@ -56,7 +56,7 @@ public:
|
|||
// This is called from the Renderer thread to notify this class about the
|
||||
// pipelines in the most recently completed render. A copy of the update
|
||||
// information is put into mUpdatesQueue.
|
||||
void NotifyPipelinesUpdated(wr::WrPipelineInfo aInfo, bool aRender);
|
||||
void NotifyPipelinesUpdated(const wr::WrPipelineInfo& aInfo, bool aRender);
|
||||
|
||||
// This is run on the compositor thread to process mUpdatesQueue. We make
|
||||
// this a public entry point because we need to invoke it from other places.
|
||||
|
|
|
@ -37,6 +37,7 @@ public:
|
|||
|
||||
virtual bool BeginFrame() = 0;
|
||||
virtual void EndFrame() = 0;
|
||||
virtual void WaitForGPU() = 0;
|
||||
virtual void Pause() = 0;
|
||||
virtual bool Resume() = 0;
|
||||
|
||||
|
|
|
@ -341,7 +341,11 @@ RenderCompositorANGLE::EndFrame()
|
|||
if (mCompositionDevice) {
|
||||
mCompositionDevice->Commit();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RenderCompositorANGLE::WaitForGPU()
|
||||
{
|
||||
// Note: this waits on the query we inserted in the previous frame,
|
||||
// not the one we just inserted now. Example:
|
||||
// Insert query #1
|
||||
|
@ -473,14 +477,31 @@ RenderCompositorANGLE::GetBufferSize()
|
|||
return mBufferSize.ref();
|
||||
}
|
||||
|
||||
void
|
||||
RenderCompositorANGLE::InsertPresentWaitQuery()
|
||||
RefPtr<ID3D11Query>
|
||||
RenderCompositorANGLE::GetD3D11Query()
|
||||
{
|
||||
RefPtr<ID3D11Query> query;
|
||||
|
||||
if (mRecycledQuery) {
|
||||
query = mRecycledQuery.forget();
|
||||
return query;
|
||||
}
|
||||
|
||||
CD3D11_QUERY_DESC desc(D3D11_QUERY_EVENT);
|
||||
HRESULT hr = mDevice->CreateQuery(&desc, getter_AddRefs(query));
|
||||
if (FAILED(hr) || !query) {
|
||||
gfxWarning() << "Could not create D3D11_QUERY_EVENT: " << gfx::hexa(hr);
|
||||
return nullptr;
|
||||
}
|
||||
return query;
|
||||
}
|
||||
|
||||
void
|
||||
RenderCompositorANGLE::InsertPresentWaitQuery()
|
||||
{
|
||||
RefPtr<ID3D11Query> query;
|
||||
query = GetD3D11Query();
|
||||
if (!query) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -498,6 +519,8 @@ RenderCompositorANGLE::WaitForPreviousPresentQuery()
|
|||
BOOL result;
|
||||
layers::WaitForGPUQuery(mDevice, mCtx, query, &result);
|
||||
|
||||
// Recycle query for later use.
|
||||
mRecycledQuery = query;
|
||||
mWaitForPresentQueries.pop();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,6 +38,7 @@ public:
|
|||
|
||||
bool BeginFrame() override;
|
||||
void EndFrame() override;
|
||||
void WaitForGPU() override;
|
||||
void Pause() override;
|
||||
bool Resume() override;
|
||||
|
||||
|
@ -61,6 +62,7 @@ protected:
|
|||
ID3D11Device* GetDeviceOfEGLDisplay();
|
||||
void CreateSwapChainForDCompIfPossible(IDXGIFactory2* aDXGIFactory2);
|
||||
bool SutdownEGLLibraryIfNecessary();
|
||||
RefPtr<ID3D11Query> GetD3D11Query();
|
||||
|
||||
EGLConfig mEGLConfig;
|
||||
EGLSurface mEGLSurface;
|
||||
|
@ -76,6 +78,7 @@ protected:
|
|||
RefPtr<IDCompositionVisual> mVisual;
|
||||
|
||||
std::queue<RefPtr<ID3D11Query>> mWaitForPresentQueries;
|
||||
RefPtr<ID3D11Query> mRecycledQuery;
|
||||
|
||||
Maybe<LayoutDeviceIntSize> mBufferSize;
|
||||
};
|
||||
|
|
|
@ -53,6 +53,11 @@ RenderCompositorOGL::EndFrame()
|
|||
mGL->SwapBuffers();
|
||||
}
|
||||
|
||||
void
|
||||
RenderCompositorOGL::WaitForGPU()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
RenderCompositorOGL::Pause()
|
||||
{
|
||||
|
|
|
@ -24,6 +24,7 @@ public:
|
|||
|
||||
bool BeginFrame() override;
|
||||
void EndFrame() override;
|
||||
void WaitForGPU() override;
|
||||
void Pause() override;
|
||||
bool Resume() override;
|
||||
|
||||
|
|
|
@ -340,7 +340,7 @@ RenderThread::RunEvent(wr::WindowId aWindowId, UniquePtr<RendererEvent> aEvent)
|
|||
|
||||
static void
|
||||
NotifyDidRender(layers::CompositorBridgeParent* aBridge,
|
||||
wr::WrPipelineInfo aInfo,
|
||||
RefPtr<WebRenderPipelineInfo> aInfo,
|
||||
TimeStamp aStart,
|
||||
TimeStamp aEnd,
|
||||
bool aRender)
|
||||
|
@ -352,15 +352,15 @@ NotifyDidRender(layers::CompositorBridgeParent* aBridge,
|
|||
aBridge->GetWrBridge()->RecordFrame();
|
||||
}
|
||||
|
||||
for (uintptr_t i = 0; i < aInfo.epochs.length; i++) {
|
||||
auto info = aInfo->Raw();
|
||||
|
||||
for (uintptr_t i = 0; i < info.epochs.length; i++) {
|
||||
aBridge->NotifyPipelineRendered(
|
||||
aInfo.epochs.data[i].pipeline_id,
|
||||
aInfo.epochs.data[i].epoch,
|
||||
info.epochs.data[i].pipeline_id,
|
||||
info.epochs.data[i].epoch,
|
||||
aStart,
|
||||
aEnd);
|
||||
}
|
||||
|
||||
wr_pipeline_info_delete(aInfo);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -382,9 +382,9 @@ RenderThread::UpdateAndRender(wr::WindowId aWindowId,
|
|||
}
|
||||
|
||||
auto& renderer = it->second;
|
||||
|
||||
bool rendered = false;
|
||||
if (aRender) {
|
||||
renderer->UpdateAndRender(aReadbackSize, aReadbackBuffer, aHadSlowFrame);
|
||||
rendered = renderer->UpdateAndRender(aReadbackSize, aReadbackBuffer, aHadSlowFrame);
|
||||
} else {
|
||||
renderer->Update();
|
||||
}
|
||||
|
@ -392,17 +392,7 @@ RenderThread::UpdateAndRender(wr::WindowId aWindowId,
|
|||
renderer->CheckGraphicsResetStatus();
|
||||
|
||||
TimeStamp end = TimeStamp::Now();
|
||||
|
||||
auto info = renderer->FlushPipelineInfo();
|
||||
RefPtr<layers::AsyncImagePipelineManager> pipelineMgr =
|
||||
renderer->GetCompositorBridge()->GetAsyncImagePipelineManager();
|
||||
// pipelineMgr should always be non-null here because it is only nulled out
|
||||
// after the WebRenderAPI instance for the CompositorBridgeParent is
|
||||
// destroyed, and that destruction blocks until the renderer thread has
|
||||
// removed the relevant renderer. And after that happens we should never reach
|
||||
// this code at all; it would bail out at the mRenderers.find check above.
|
||||
MOZ_ASSERT(pipelineMgr);
|
||||
pipelineMgr->NotifyPipelinesUpdated(info, aRender);
|
||||
|
||||
layers::CompositorThreadHolder::Loop()->PostTask(NewRunnableFunction(
|
||||
"NotifyDidRenderRunnable",
|
||||
|
@ -412,6 +402,25 @@ RenderThread::UpdateAndRender(wr::WindowId aWindowId,
|
|||
aStartTime, end,
|
||||
aRender
|
||||
));
|
||||
|
||||
if (rendered) {
|
||||
// Wait for GPU after posting NotifyDidRender, since the wait is not
|
||||
// necessary for the NotifyDidRender.
|
||||
// The wait is necessary for Textures recycling of AsyncImagePipelineManager
|
||||
// and for avoiding GPU queue is filled with too much tasks.
|
||||
// WaitForGPU's implementation is different for each platform.
|
||||
renderer->WaitForGPU();
|
||||
}
|
||||
|
||||
RefPtr<layers::AsyncImagePipelineManager> pipelineMgr =
|
||||
renderer->GetCompositorBridge()->GetAsyncImagePipelineManager();
|
||||
// pipelineMgr should always be non-null here because it is only nulled out
|
||||
// after the WebRenderAPI instance for the CompositorBridgeParent is
|
||||
// destroyed, and that destruction blocks until the renderer thread has
|
||||
// removed the relevant renderer. And after that happens we should never reach
|
||||
// this code at all; it would bail out at the mRenderers.find check above.
|
||||
MOZ_ASSERT(pipelineMgr);
|
||||
pipelineMgr->NotifyPipelinesUpdated(info->Raw(), aRender);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -795,6 +804,16 @@ WebRenderShaders::~WebRenderShaders() {
|
|||
wr_shaders_delete(mShaders, mGL.get());
|
||||
}
|
||||
|
||||
WebRenderPipelineInfo::WebRenderPipelineInfo(wr::WrPipelineInfo aPipelineInfo)
|
||||
: mPipelineInfo(aPipelineInfo)
|
||||
{
|
||||
}
|
||||
|
||||
WebRenderPipelineInfo::~WebRenderPipelineInfo()
|
||||
{
|
||||
wr_pipeline_info_delete(mPipelineInfo);
|
||||
}
|
||||
|
||||
WebRenderThreadPool::WebRenderThreadPool()
|
||||
{
|
||||
mThreadPool = wr_thread_pool_new();
|
||||
|
|
|
@ -72,6 +72,19 @@ protected:
|
|||
wr::WrShaders* mShaders;
|
||||
};
|
||||
|
||||
class WebRenderPipelineInfo {
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(WebRenderPipelineInfo);
|
||||
public:
|
||||
explicit WebRenderPipelineInfo(wr::WrPipelineInfo aPipelineInfo);
|
||||
|
||||
const wr::WrPipelineInfo& Raw() { return mPipelineInfo; }
|
||||
|
||||
protected:
|
||||
~WebRenderPipelineInfo();
|
||||
|
||||
const wr::WrPipelineInfo mPipelineInfo;
|
||||
};
|
||||
|
||||
/// Base class for an event that can be scheduled to run on the render thread.
|
||||
///
|
||||
/// The event can be passed through the same channels as regular WebRender messages
|
||||
|
|
|
@ -194,6 +194,12 @@ RendererOGL::CheckGraphicsResetStatus()
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
RendererOGL::WaitForGPU()
|
||||
{
|
||||
mCompositor->WaitForGPU();
|
||||
}
|
||||
|
||||
void
|
||||
RendererOGL::Pause()
|
||||
{
|
||||
|
@ -229,10 +235,11 @@ RendererOGL::SetFrameStartTime(const TimeStamp& aTime)
|
|||
mFrameStartTime = aTime;
|
||||
}
|
||||
|
||||
wr::WrPipelineInfo
|
||||
RefPtr<WebRenderPipelineInfo>
|
||||
RendererOGL::FlushPipelineInfo()
|
||||
{
|
||||
return wr_renderer_flush_pipeline_info(mRenderer);
|
||||
auto info = wr_renderer_flush_pipeline_info(mRenderer);
|
||||
return new WebRenderPipelineInfo(info);
|
||||
}
|
||||
|
||||
RenderTextureHost*
|
||||
|
|
|
@ -60,7 +60,7 @@ public:
|
|||
bool UpdateAndRender(const Maybe<gfx::IntSize>& aReadbackSize, const Maybe<Range<uint8_t>>& aReadbackBuffer, bool aHadSlowFrame);
|
||||
|
||||
/// This can be called on the render thread only.
|
||||
bool RenderToTarget(gfx::DrawTarget& aTarget);
|
||||
void WaitForGPU();
|
||||
|
||||
/// This can be called on the render thread only.
|
||||
void SetProfilerEnabled(bool aEnabled);
|
||||
|
@ -91,7 +91,7 @@ public:
|
|||
|
||||
layers::CompositorBridgeParent* GetCompositorBridge() { return mBridge; }
|
||||
|
||||
wr::WrPipelineInfo FlushPipelineInfo();
|
||||
RefPtr<WebRenderPipelineInfo> FlushPipelineInfo();
|
||||
|
||||
RenderTextureHost* GetRenderTexture(wr::WrExternalImageId aExternalImageId);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче