2017-10-28 02:10:06 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
2017-01-06 21:10:15 +03:00
|
|
|
/* 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/. */
|
|
|
|
|
2017-06-09 06:56:13 +03:00
|
|
|
#include "base/task.h"
|
|
|
|
#include "GeckoProfiler.h"
|
2017-01-06 21:10:15 +03:00
|
|
|
#include "RenderThread.h"
|
|
|
|
#include "nsThreadUtils.h"
|
2017-07-03 15:08:22 +03:00
|
|
|
#include "mtransport/runnable_utils.h"
|
2017-01-27 23:30:18 +03:00
|
|
|
#include "mozilla/layers/CompositorThread.h"
|
|
|
|
#include "mozilla/layers/CompositorBridgeParent.h"
|
2017-01-06 21:10:15 +03:00
|
|
|
#include "mozilla/StaticPtr.h"
|
2017-03-07 13:37:28 +03:00
|
|
|
#include "mozilla/webrender/RendererOGL.h"
|
2017-03-31 17:29:14 +03:00
|
|
|
#include "mozilla/webrender/RenderTextureHost.h"
|
2017-03-07 13:37:28 +03:00
|
|
|
#include "mozilla/widget/CompositorWidget.h"
|
2017-01-06 21:10:15 +03:00
|
|
|
|
|
|
|
namespace mozilla {
|
2017-01-17 03:22:09 +03:00
|
|
|
namespace wr {
|
2017-01-06 21:10:15 +03:00
|
|
|
|
|
|
|
static StaticRefPtr<RenderThread> sRenderThread;
|
|
|
|
|
|
|
|
RenderThread::RenderThread(base::Thread* aThread)
|
2017-01-25 00:06:17 +03:00
|
|
|
: mThread(aThread)
|
2017-11-03 05:22:28 +03:00
|
|
|
, mFrameCountMapLock("RenderThread.mFrameCountMapLock")
|
2017-03-07 13:37:28 +03:00
|
|
|
, mRenderTextureMapLock("RenderThread.mRenderTextureMapLock")
|
2017-07-03 15:08:22 +03:00
|
|
|
, mHasShutdown(false)
|
2017-01-06 21:10:15 +03:00
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
RenderThread::~RenderThread()
|
|
|
|
{
|
|
|
|
delete mThread;
|
|
|
|
}
|
|
|
|
|
2017-01-17 03:22:09 +03:00
|
|
|
// static
|
2017-01-06 21:10:15 +03:00
|
|
|
RenderThread*
|
|
|
|
RenderThread::Get()
|
|
|
|
{
|
|
|
|
return sRenderThread;
|
|
|
|
}
|
|
|
|
|
|
|
|
// static
|
|
|
|
void
|
|
|
|
RenderThread::Start()
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
MOZ_ASSERT(!sRenderThread);
|
|
|
|
|
2017-01-11 15:51:27 +03:00
|
|
|
base::Thread* thread = new base::Thread("Renderer");
|
2017-01-06 21:10:15 +03:00
|
|
|
|
|
|
|
base::Thread::Options options;
|
|
|
|
// TODO(nical): The compositor thread has a bunch of specific options, see
|
|
|
|
// which ones make sense here.
|
|
|
|
if (!thread->StartWithOptions(options)) {
|
|
|
|
delete thread;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
sRenderThread = new RenderThread(thread);
|
|
|
|
}
|
|
|
|
|
|
|
|
// static
|
|
|
|
void
|
|
|
|
RenderThread::ShutDown()
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
MOZ_ASSERT(sRenderThread);
|
|
|
|
|
2017-07-03 15:08:22 +03:00
|
|
|
{
|
|
|
|
MutexAutoLock lock(sRenderThread->mRenderTextureMapLock);
|
|
|
|
sRenderThread->mHasShutdown = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
layers::SynchronousTask task("RenderThread");
|
|
|
|
RefPtr<Runnable> runnable = WrapRunnable(
|
|
|
|
RefPtr<RenderThread>(sRenderThread.get()),
|
|
|
|
&RenderThread::ShutDownTask,
|
|
|
|
&task);
|
|
|
|
sRenderThread->Loop()->PostTask(runnable.forget());
|
|
|
|
task.Wait();
|
2017-01-06 21:10:15 +03:00
|
|
|
|
|
|
|
sRenderThread = nullptr;
|
|
|
|
}
|
|
|
|
|
2017-07-03 15:08:22 +03:00
|
|
|
void
|
|
|
|
RenderThread::ShutDownTask(layers::SynchronousTask* aTask)
|
|
|
|
{
|
|
|
|
layers::AutoCompleteTask complete(aTask);
|
|
|
|
MOZ_ASSERT(IsInRenderThread());
|
|
|
|
}
|
|
|
|
|
2017-01-06 21:10:15 +03:00
|
|
|
// static
|
|
|
|
MessageLoop*
|
|
|
|
RenderThread::Loop()
|
|
|
|
{
|
|
|
|
return sRenderThread ? sRenderThread->mThread->message_loop() : nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
// static
|
|
|
|
bool
|
|
|
|
RenderThread::IsInRenderThread()
|
|
|
|
{
|
|
|
|
return sRenderThread && sRenderThread->mThread->thread_id() == PlatformThread::CurrentId();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2017-01-17 03:22:09 +03:00
|
|
|
RenderThread::AddRenderer(wr::WindowId aWindowId, UniquePtr<RendererOGL> aRenderer)
|
2017-01-06 21:10:15 +03:00
|
|
|
{
|
2017-01-16 17:22:47 +03:00
|
|
|
MOZ_ASSERT(IsInRenderThread());
|
2017-07-03 15:08:22 +03:00
|
|
|
|
|
|
|
if (mHasShutdown) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-01-06 21:10:15 +03:00
|
|
|
mRenderers[aWindowId] = Move(aRenderer);
|
2017-05-19 03:21:38 +03:00
|
|
|
|
2017-11-03 05:22:28 +03:00
|
|
|
MutexAutoLock lock(mFrameCountMapLock);
|
2017-11-24 12:34:50 +03:00
|
|
|
mWindowInfos.Put(AsUint64(aWindowId), WindowInfo());
|
2017-01-06 21:10:15 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2017-01-17 03:22:09 +03:00
|
|
|
RenderThread::RemoveRenderer(wr::WindowId aWindowId)
|
2017-01-06 21:10:15 +03:00
|
|
|
{
|
2017-01-16 17:22:47 +03:00
|
|
|
MOZ_ASSERT(IsInRenderThread());
|
2017-07-03 15:08:22 +03:00
|
|
|
|
|
|
|
if (mHasShutdown) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-01-06 21:10:15 +03:00
|
|
|
mRenderers.erase(aWindowId);
|
2017-05-19 03:21:38 +03:00
|
|
|
|
2017-11-03 05:22:28 +03:00
|
|
|
MutexAutoLock lock(mFrameCountMapLock);
|
2017-11-24 12:34:50 +03:00
|
|
|
mWindowInfos.Remove(AsUint64(aWindowId));
|
2017-01-06 21:10:15 +03:00
|
|
|
}
|
|
|
|
|
2017-01-16 17:22:47 +03:00
|
|
|
RendererOGL*
|
2017-01-17 03:22:09 +03:00
|
|
|
RenderThread::GetRenderer(wr::WindowId aWindowId)
|
2017-01-16 17:22:47 +03:00
|
|
|
{
|
|
|
|
MOZ_ASSERT(IsInRenderThread());
|
|
|
|
|
|
|
|
auto it = mRenderers.find(aWindowId);
|
|
|
|
MOZ_ASSERT(it != mRenderers.end());
|
|
|
|
|
|
|
|
if (it == mRenderers.end()) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2017-01-25 00:20:54 +03:00
|
|
|
return it->second.get();
|
2017-01-16 17:22:47 +03:00
|
|
|
}
|
2017-01-06 21:10:15 +03:00
|
|
|
|
|
|
|
void
|
2017-01-17 03:22:09 +03:00
|
|
|
RenderThread::NewFrameReady(wr::WindowId aWindowId)
|
2017-01-06 21:10:15 +03:00
|
|
|
{
|
2017-07-03 15:08:22 +03:00
|
|
|
if (mHasShutdown) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-01-06 21:10:15 +03:00
|
|
|
if (!IsInRenderThread()) {
|
2017-06-12 22:34:10 +03:00
|
|
|
Loop()->PostTask(
|
|
|
|
NewRunnableMethod<wr::WindowId>("wr::RenderThread::NewFrameReady",
|
|
|
|
this,
|
|
|
|
&RenderThread::NewFrameReady,
|
|
|
|
aWindowId));
|
2017-01-06 21:10:15 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-11-24 12:34:50 +03:00
|
|
|
if (IsDestroyed(aWindowId)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-01-06 21:10:15 +03:00
|
|
|
UpdateAndRender(aWindowId);
|
2017-05-19 03:21:38 +03:00
|
|
|
DecPendingFrameCount(aWindowId);
|
2017-01-06 21:10:15 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2017-01-17 03:22:09 +03:00
|
|
|
RenderThread::RunEvent(wr::WindowId aWindowId, UniquePtr<RendererEvent> aEvent)
|
2017-01-06 21:10:15 +03:00
|
|
|
{
|
|
|
|
if (!IsInRenderThread()) {
|
2017-06-12 22:34:10 +03:00
|
|
|
Loop()->PostTask(
|
|
|
|
NewRunnableMethod<wr::WindowId, UniquePtr<RendererEvent>&&>(
|
|
|
|
"wr::RenderThread::RunEvent",
|
|
|
|
this,
|
|
|
|
&RenderThread::RunEvent,
|
|
|
|
aWindowId,
|
|
|
|
Move(aEvent)));
|
2017-01-11 15:51:27 +03:00
|
|
|
return;
|
2017-01-06 21:10:15 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
aEvent->Run(*this, aWindowId);
|
|
|
|
aEvent = nullptr;
|
|
|
|
}
|
|
|
|
|
2017-01-27 23:30:18 +03:00
|
|
|
static void
|
|
|
|
NotifyDidRender(layers::CompositorBridgeParentBase* aBridge,
|
2017-06-28 02:20:36 +03:00
|
|
|
wr::WrRenderedEpochs* aEpochs,
|
2017-01-27 23:30:18 +03:00
|
|
|
TimeStamp aStart,
|
|
|
|
TimeStamp aEnd)
|
|
|
|
{
|
2017-06-28 02:20:36 +03:00
|
|
|
wr::WrPipelineId pipeline;
|
|
|
|
wr::WrEpoch epoch;
|
2017-01-27 23:30:18 +03:00
|
|
|
while (wr_rendered_epochs_next(aEpochs, &pipeline, &epoch)) {
|
2017-02-24 06:22:59 +03:00
|
|
|
aBridge->NotifyDidCompositeToPipeline(pipeline, epoch, aStart, aEnd);
|
2017-01-27 23:30:18 +03:00
|
|
|
}
|
|
|
|
wr_rendered_epochs_delete(aEpochs);
|
|
|
|
}
|
2017-01-06 21:10:15 +03:00
|
|
|
|
|
|
|
void
|
2017-01-17 03:22:09 +03:00
|
|
|
RenderThread::UpdateAndRender(wr::WindowId aWindowId)
|
2017-01-06 21:10:15 +03:00
|
|
|
{
|
2017-10-04 01:11:18 +03:00
|
|
|
AUTO_PROFILER_TRACING("Paint", "Composite");
|
2017-01-16 17:22:47 +03:00
|
|
|
MOZ_ASSERT(IsInRenderThread());
|
|
|
|
|
2017-01-06 21:10:15 +03:00
|
|
|
auto it = mRenderers.find(aWindowId);
|
|
|
|
MOZ_ASSERT(it != mRenderers.end());
|
|
|
|
if (it == mRenderers.end()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto& renderer = it->second;
|
2017-01-27 23:30:18 +03:00
|
|
|
TimeStamp start = TimeStamp::Now();
|
2017-01-06 21:10:15 +03:00
|
|
|
|
2018-02-01 05:34:43 +03:00
|
|
|
bool ret = renderer->UpdateAndRender();
|
2017-07-04 13:25:24 +03:00
|
|
|
if (!ret) {
|
|
|
|
// Render did not happen, do not call NotifyDidRender.
|
|
|
|
return;
|
|
|
|
}
|
2017-01-27 23:30:18 +03:00
|
|
|
|
|
|
|
TimeStamp end = TimeStamp::Now();
|
|
|
|
|
|
|
|
auto epochs = renderer->FlushRenderedEpochs();
|
|
|
|
layers::CompositorThreadHolder::Loop()->PostTask(NewRunnableFunction(
|
2017-10-27 23:39:28 +03:00
|
|
|
"NotifyDidRenderRunnable",
|
2017-01-27 23:30:18 +03:00
|
|
|
&NotifyDidRender,
|
|
|
|
renderer->GetCompositorBridge(),
|
|
|
|
epochs,
|
|
|
|
start, end
|
|
|
|
));
|
2017-01-06 21:10:15 +03:00
|
|
|
}
|
|
|
|
|
2017-04-05 17:12:11 +03:00
|
|
|
void
|
|
|
|
RenderThread::Pause(wr::WindowId aWindowId)
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(IsInRenderThread());
|
|
|
|
|
|
|
|
auto it = mRenderers.find(aWindowId);
|
|
|
|
MOZ_ASSERT(it != mRenderers.end());
|
|
|
|
if (it == mRenderers.end()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
auto& renderer = it->second;
|
|
|
|
renderer->Pause();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
RenderThread::Resume(wr::WindowId aWindowId)
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(IsInRenderThread());
|
|
|
|
|
|
|
|
auto it = mRenderers.find(aWindowId);
|
|
|
|
MOZ_ASSERT(it != mRenderers.end());
|
|
|
|
if (it == mRenderers.end()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
auto& renderer = it->second;
|
|
|
|
return renderer->Resume();
|
|
|
|
}
|
|
|
|
|
2017-11-03 05:22:28 +03:00
|
|
|
bool
|
|
|
|
RenderThread::TooManyPendingFrames(wr::WindowId aWindowId)
|
2017-05-19 03:21:38 +03:00
|
|
|
{
|
2017-11-03 05:22:28 +03:00
|
|
|
const int64_t maxFrameCount = 1;
|
|
|
|
|
|
|
|
// Too many pending frames if pending frames exit more than maxFrameCount
|
|
|
|
// or if RenderBackend is still processing a frame.
|
|
|
|
|
|
|
|
MutexAutoLock lock(mFrameCountMapLock);
|
2017-11-24 12:34:50 +03:00
|
|
|
WindowInfo info;
|
|
|
|
if (!mWindowInfos.Get(AsUint64(aWindowId), &info)) {
|
2017-11-03 05:22:28 +03:00
|
|
|
MOZ_ASSERT(false);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-11-24 12:34:50 +03:00
|
|
|
if (info.mPendingCount > maxFrameCount) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
MOZ_ASSERT(info.mPendingCount >= info.mRenderingCount);
|
|
|
|
return info.mPendingCount > info.mRenderingCount;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
RenderThread::IsDestroyed(wr::WindowId aWindowId)
|
|
|
|
{
|
|
|
|
MutexAutoLock lock(mFrameCountMapLock);
|
|
|
|
WindowInfo info;
|
|
|
|
if (!mWindowInfos.Get(AsUint64(aWindowId), &info)) {
|
2017-11-03 05:22:28 +03:00
|
|
|
return true;
|
|
|
|
}
|
2017-11-24 12:34:50 +03:00
|
|
|
|
|
|
|
return info.mIsDestroyed;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
RenderThread::SetDestroyed(wr::WindowId aWindowId)
|
|
|
|
{
|
|
|
|
MutexAutoLock lock(mFrameCountMapLock);
|
|
|
|
WindowInfo info;
|
|
|
|
if (!mWindowInfos.Get(AsUint64(aWindowId), &info)) {
|
|
|
|
MOZ_ASSERT(false);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
info.mIsDestroyed = true;
|
|
|
|
mWindowInfos.Put(AsUint64(aWindowId), info);
|
2017-05-19 03:21:38 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
RenderThread::IncPendingFrameCount(wr::WindowId aWindowId)
|
|
|
|
{
|
2017-11-03 05:22:28 +03:00
|
|
|
MutexAutoLock lock(mFrameCountMapLock);
|
2017-05-19 03:21:38 +03:00
|
|
|
// Get the old count.
|
2017-11-24 12:34:50 +03:00
|
|
|
WindowInfo info;
|
|
|
|
if (!mWindowInfos.Get(AsUint64(aWindowId), &info)) {
|
2017-05-19 03:21:38 +03:00
|
|
|
MOZ_ASSERT(false);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
// Update pending frame count.
|
2017-11-24 12:34:50 +03:00
|
|
|
info.mPendingCount = info.mPendingCount + 1;
|
|
|
|
mWindowInfos.Put(AsUint64(aWindowId), info);
|
2017-11-03 05:22:28 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
RenderThread::IncRenderingFrameCount(wr::WindowId aWindowId)
|
|
|
|
{
|
|
|
|
MutexAutoLock lock(mFrameCountMapLock);
|
|
|
|
// Get the old count.
|
2017-11-24 12:34:50 +03:00
|
|
|
WindowInfo info;
|
|
|
|
if (!mWindowInfos.Get(AsUint64(aWindowId), &info)) {
|
2017-11-03 05:22:28 +03:00
|
|
|
MOZ_ASSERT(false);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
// Update rendering frame count.
|
2017-11-24 12:34:50 +03:00
|
|
|
info.mRenderingCount = info.mRenderingCount + 1;
|
|
|
|
mWindowInfos.Put(AsUint64(aWindowId), info);
|
2017-05-19 03:21:38 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
RenderThread::DecPendingFrameCount(wr::WindowId aWindowId)
|
|
|
|
{
|
2017-11-03 05:22:28 +03:00
|
|
|
MutexAutoLock lock(mFrameCountMapLock);
|
2017-05-19 03:21:38 +03:00
|
|
|
// Get the old count.
|
2017-11-24 12:34:50 +03:00
|
|
|
WindowInfo info;
|
|
|
|
if (!mWindowInfos.Get(AsUint64(aWindowId), &info)) {
|
2017-05-19 03:21:38 +03:00
|
|
|
MOZ_ASSERT(false);
|
|
|
|
return;
|
|
|
|
}
|
2017-11-24 12:34:50 +03:00
|
|
|
MOZ_ASSERT(info.mPendingCount > 0);
|
|
|
|
MOZ_ASSERT(info.mRenderingCount > 0);
|
|
|
|
if (info.mPendingCount <= 0) {
|
2017-05-19 03:21:38 +03:00
|
|
|
return;
|
|
|
|
}
|
2017-11-03 05:22:28 +03:00
|
|
|
// Update frame counts.
|
2017-11-24 12:34:50 +03:00
|
|
|
info.mPendingCount = info.mPendingCount - 1;
|
|
|
|
info.mRenderingCount = info.mRenderingCount - 1;
|
|
|
|
mWindowInfos.Put(AsUint64(aWindowId), info);
|
2017-05-19 03:21:38 +03:00
|
|
|
}
|
|
|
|
|
2017-03-07 13:37:28 +03:00
|
|
|
void
|
2017-06-07 18:44:05 +03:00
|
|
|
RenderThread::RegisterExternalImage(uint64_t aExternalImageId, already_AddRefed<RenderTextureHost> aTexture)
|
2017-03-07 13:37:28 +03:00
|
|
|
{
|
|
|
|
MutexAutoLock lock(mRenderTextureMapLock);
|
2017-06-07 18:44:05 +03:00
|
|
|
|
2017-07-03 15:08:22 +03:00
|
|
|
if (mHasShutdown) {
|
|
|
|
return;
|
|
|
|
}
|
2017-06-28 02:03:16 +03:00
|
|
|
MOZ_ASSERT(!mRenderTextures.GetWeak(aExternalImageId));
|
|
|
|
mRenderTextures.Put(aExternalImageId, Move(aTexture));
|
2017-03-07 13:37:28 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
RenderThread::UnregisterExternalImage(uint64_t aExternalImageId)
|
|
|
|
{
|
|
|
|
MutexAutoLock lock(mRenderTextureMapLock);
|
2017-07-03 15:08:22 +03:00
|
|
|
if (mHasShutdown) {
|
|
|
|
return;
|
|
|
|
}
|
2017-06-28 02:03:16 +03:00
|
|
|
MOZ_ASSERT(mRenderTextures.GetWeak(aExternalImageId));
|
2017-06-07 18:44:05 +03:00
|
|
|
if (!IsInRenderThread()) {
|
|
|
|
// The RenderTextureHost should be released in render thread. So, post the
|
|
|
|
// deletion task here.
|
|
|
|
// The shmem and raw buffer are owned by compositor ipc channel. It's
|
|
|
|
// possible that RenderTextureHost is still exist after the shmem/raw buffer
|
|
|
|
// deletion. Then the buffer in RenderTextureHost becomes invalid. It's fine
|
|
|
|
// for this situation. Gecko will only release the buffer if WR doesn't need
|
|
|
|
// it. So, no one will access the invalid buffer in RenderTextureHost.
|
2017-06-28 02:03:16 +03:00
|
|
|
RefPtr<RenderTextureHost> texture;
|
|
|
|
mRenderTextures.Remove(aExternalImageId, getter_AddRefs(texture));
|
2017-06-07 18:44:05 +03:00
|
|
|
Loop()->PostTask(NewRunnableMethod<RefPtr<RenderTextureHost>>(
|
2017-06-12 22:34:10 +03:00
|
|
|
"RenderThread::DeferredRenderTextureHostDestroy",
|
2017-06-07 18:44:05 +03:00
|
|
|
this, &RenderThread::DeferredRenderTextureHostDestroy, Move(texture)
|
|
|
|
));
|
|
|
|
} else {
|
|
|
|
mRenderTextures.Remove(aExternalImageId);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
RenderThread::DeferredRenderTextureHostDestroy(RefPtr<RenderTextureHost>)
|
|
|
|
{
|
|
|
|
// Do nothing. Just decrease the ref-count of RenderTextureHost.
|
2017-03-07 13:37:28 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
RenderTextureHost*
|
2017-06-28 02:20:36 +03:00
|
|
|
RenderThread::GetRenderTexture(wr::WrExternalImageId aExternalImageId)
|
2017-03-07 13:37:28 +03:00
|
|
|
{
|
2017-06-07 18:44:05 +03:00
|
|
|
MOZ_ASSERT(IsInRenderThread());
|
|
|
|
|
2017-03-07 13:37:28 +03:00
|
|
|
MutexAutoLock lock(mRenderTextureMapLock);
|
2017-06-28 02:03:16 +03:00
|
|
|
MOZ_ASSERT(mRenderTextures.GetWeak(aExternalImageId.mHandle));
|
|
|
|
return mRenderTextures.GetWeak(aExternalImageId.mHandle);
|
2017-03-07 13:37:28 +03:00
|
|
|
}
|
|
|
|
|
2017-11-24 14:58:24 +03:00
|
|
|
WebRenderProgramCache*
|
|
|
|
RenderThread::ProgramCache()
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(IsInRenderThread());
|
|
|
|
|
|
|
|
if (!mProgramCache) {
|
|
|
|
mProgramCache = MakeUnique<WebRenderProgramCache>();
|
|
|
|
}
|
|
|
|
return mProgramCache.get();
|
|
|
|
}
|
|
|
|
|
2017-06-13 18:57:16 +03:00
|
|
|
WebRenderThreadPool::WebRenderThreadPool()
|
|
|
|
{
|
|
|
|
mThreadPool = wr_thread_pool_new();
|
|
|
|
}
|
|
|
|
|
|
|
|
WebRenderThreadPool::~WebRenderThreadPool()
|
|
|
|
{
|
|
|
|
wr_thread_pool_delete(mThreadPool);
|
|
|
|
}
|
|
|
|
|
2017-11-24 14:58:24 +03:00
|
|
|
WebRenderProgramCache::WebRenderProgramCache()
|
|
|
|
{
|
|
|
|
mProgramCache = wr_program_cache_new();
|
|
|
|
}
|
|
|
|
|
|
|
|
WebRenderProgramCache::~WebRenderProgramCache()
|
|
|
|
{
|
|
|
|
wr_program_cache_delete(mProgramCache);
|
|
|
|
}
|
|
|
|
|
2017-01-25 00:06:17 +03:00
|
|
|
} // namespace wr
|
|
|
|
} // namespace mozilla
|
2017-01-06 21:10:15 +03:00
|
|
|
|
|
|
|
extern "C" {
|
|
|
|
|
2018-01-17 19:19:39 +03:00
|
|
|
static void NewFrameReady(mozilla::wr::WrWindowId aWindowId)
|
2017-01-06 21:10:15 +03:00
|
|
|
{
|
2017-11-03 05:22:28 +03:00
|
|
|
mozilla::wr::RenderThread::Get()->IncRenderingFrameCount(aWindowId);
|
2017-01-17 03:22:09 +03:00
|
|
|
mozilla::wr::RenderThread::Get()->NewFrameReady(mozilla::wr::WindowId(aWindowId));
|
2017-01-06 21:10:15 +03:00
|
|
|
}
|
|
|
|
|
2018-01-17 19:19:39 +03:00
|
|
|
void wr_notifier_new_frame_ready(mozilla::wr::WrWindowId aWindowId)
|
|
|
|
{
|
|
|
|
NewFrameReady(aWindowId);
|
|
|
|
}
|
|
|
|
|
2017-06-28 02:20:36 +03:00
|
|
|
void wr_notifier_new_scroll_frame_ready(mozilla::wr::WrWindowId aWindowId, bool aCompositeNeeded)
|
2017-01-06 21:10:15 +03:00
|
|
|
{
|
2018-01-17 19:19:39 +03:00
|
|
|
// If we sent a transaction that contained both scrolling updates and a
|
|
|
|
// GenerateFrame, we can get this function called with aCompositeNeeded=true
|
|
|
|
// instead of wr_notifier_new_frame_ready. In that case we want to update the
|
|
|
|
// rendering.
|
|
|
|
if (aCompositeNeeded) {
|
|
|
|
NewFrameReady(aWindowId);
|
|
|
|
}
|
2017-01-06 21:10:15 +03:00
|
|
|
}
|
|
|
|
|
2017-06-28 02:20:36 +03:00
|
|
|
void wr_notifier_external_event(mozilla::wr::WrWindowId aWindowId, size_t aRawEvent)
|
2017-01-06 21:10:15 +03:00
|
|
|
{
|
2017-01-17 03:22:09 +03:00
|
|
|
mozilla::UniquePtr<mozilla::wr::RendererEvent> evt(
|
|
|
|
reinterpret_cast<mozilla::wr::RendererEvent*>(aRawEvent));
|
|
|
|
mozilla::wr::RenderThread::Get()->RunEvent(mozilla::wr::WindowId(aWindowId),
|
|
|
|
mozilla::Move(evt));
|
2017-01-06 21:10:15 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
} // extern C
|