2016-11-16 16:54:51 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim: set sw=4 ts=8 et tw=80 : */
|
|
|
|
/* 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 "mozilla/layers/WebRenderBridgeParent.h"
|
|
|
|
|
2017-05-28 14:48:36 +03:00
|
|
|
#include "apz/src/AsyncPanZoomController.h"
|
2016-11-24 09:48:01 +03:00
|
|
|
#include "CompositableHost.h"
|
2017-04-27 19:04:25 +03:00
|
|
|
#include "gfxPrefs.h"
|
2017-06-09 06:56:13 +03:00
|
|
|
#include "GeckoProfiler.h"
|
2016-11-16 16:54:51 +03:00
|
|
|
#include "GLContext.h"
|
|
|
|
#include "GLContextProvider.h"
|
2017-01-13 13:25:07 +03:00
|
|
|
#include "mozilla/Range.h"
|
2017-03-28 12:11:03 +03:00
|
|
|
#include "mozilla/layers/AnimationHelper.h"
|
2017-04-20 17:38:06 +03:00
|
|
|
#include "mozilla/layers/APZCTreeManager.h"
|
2016-11-17 12:02:56 +03:00
|
|
|
#include "mozilla/layers/Compositor.h"
|
2016-11-30 05:59:14 +03:00
|
|
|
#include "mozilla/layers/CompositorBridgeParent.h"
|
2016-12-02 01:10:10 +03:00
|
|
|
#include "mozilla/layers/CompositorThread.h"
|
2016-11-22 05:56:38 +03:00
|
|
|
#include "mozilla/layers/CompositorVsyncScheduler.h"
|
2017-01-05 18:03:17 +03:00
|
|
|
#include "mozilla/layers/ImageBridgeParent.h"
|
2016-11-28 05:39:42 +03:00
|
|
|
#include "mozilla/layers/ImageDataSerializer.h"
|
|
|
|
#include "mozilla/layers/TextureHost.h"
|
2017-07-25 12:36:11 +03:00
|
|
|
#include "mozilla/layers/WebRenderCompositableHolder.h"
|
2017-04-27 19:34:54 +03:00
|
|
|
#include "mozilla/layers/WebRenderImageHost.h"
|
2017-03-07 13:37:28 +03:00
|
|
|
#include "mozilla/layers/WebRenderTextureHost.h"
|
2017-04-27 19:34:54 +03:00
|
|
|
#include "mozilla/TimeStamp.h"
|
2017-06-30 04:06:11 +03:00
|
|
|
#include "mozilla/Unused.h"
|
2017-01-17 03:21:52 +03:00
|
|
|
#include "mozilla/webrender/RenderThread.h"
|
2016-11-28 05:39:42 +03:00
|
|
|
#include "mozilla/widget/CompositorWidget.h"
|
2016-11-16 16:54:51 +03:00
|
|
|
|
2017-03-02 04:36:27 +03:00
|
|
|
bool is_in_main_thread()
|
|
|
|
{
|
|
|
|
return NS_IsMainThread();
|
|
|
|
}
|
|
|
|
|
2016-12-02 01:10:10 +03:00
|
|
|
bool is_in_compositor_thread()
|
|
|
|
{
|
|
|
|
return mozilla::layers::CompositorThreadHolder::IsInCompositorThread();
|
|
|
|
}
|
|
|
|
|
2017-01-06 21:10:15 +03:00
|
|
|
bool is_in_render_thread()
|
|
|
|
{
|
2017-01-17 03:22:09 +03:00
|
|
|
return mozilla::wr::RenderThread::IsInRenderThread();
|
2017-01-06 21:10:15 +03:00
|
|
|
}
|
|
|
|
|
2017-03-20 19:10:40 +03:00
|
|
|
bool is_glcontext_egl(void* glcontext_ptr)
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(glcontext_ptr);
|
|
|
|
|
|
|
|
mozilla::gl::GLContext* glcontext = reinterpret_cast<mozilla::gl::GLContext*>(glcontext_ptr);
|
|
|
|
if (!glcontext) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return glcontext->GetContextType() == mozilla::gl::GLContextType::EGL;
|
|
|
|
}
|
|
|
|
|
2017-07-17 08:38:22 +03:00
|
|
|
bool gfx_use_wrench()
|
|
|
|
{
|
|
|
|
return gfxEnv::EnableWebRenderRecording();
|
|
|
|
}
|
|
|
|
|
2017-03-27 21:32:39 +03:00
|
|
|
void gfx_critical_note(const char* msg)
|
|
|
|
{
|
|
|
|
gfxCriticalNote << msg;
|
|
|
|
}
|
|
|
|
|
2016-12-21 07:22:04 +03:00
|
|
|
void* get_proc_address_from_glcontext(void* glcontext_ptr, const char* procname)
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(glcontext_ptr);
|
|
|
|
|
|
|
|
mozilla::gl::GLContext* glcontext = reinterpret_cast<mozilla::gl::GLContext*>(glcontext_ptr);
|
|
|
|
if (!glcontext) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
PRFuncPtr p = glcontext->LookupSymbol(procname);
|
|
|
|
return reinterpret_cast<void*>(p);
|
|
|
|
}
|
|
|
|
|
2016-11-16 16:54:51 +03:00
|
|
|
namespace mozilla {
|
|
|
|
namespace layers {
|
|
|
|
|
2016-11-28 05:39:42 +03:00
|
|
|
using namespace mozilla::gfx;
|
|
|
|
|
2016-12-07 13:02:04 +03:00
|
|
|
class MOZ_STACK_CLASS AutoWebRenderBridgeParentAsyncMessageSender
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
explicit AutoWebRenderBridgeParentAsyncMessageSender(WebRenderBridgeParent* aWebRenderBridgeParent,
|
|
|
|
InfallibleTArray<OpDestroy>* aDestroyActors = nullptr)
|
|
|
|
: mWebRenderBridgeParent(aWebRenderBridgeParent)
|
|
|
|
, mActorsToDestroy(aDestroyActors)
|
|
|
|
{
|
|
|
|
mWebRenderBridgeParent->SetAboutToSendAsyncMessages();
|
|
|
|
}
|
|
|
|
|
|
|
|
~AutoWebRenderBridgeParentAsyncMessageSender()
|
|
|
|
{
|
|
|
|
mWebRenderBridgeParent->SendPendingAsyncMessages();
|
|
|
|
if (mActorsToDestroy) {
|
|
|
|
// Destroy the actors after sending the async messages because the latter may contain
|
|
|
|
// references to some actors.
|
|
|
|
for (const auto& op : *mActorsToDestroy) {
|
|
|
|
mWebRenderBridgeParent->DestroyActor(op);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
private:
|
|
|
|
WebRenderBridgeParent* mWebRenderBridgeParent;
|
|
|
|
InfallibleTArray<OpDestroy>* mActorsToDestroy;
|
|
|
|
};
|
|
|
|
|
2017-02-27 06:16:11 +03:00
|
|
|
/* static */ uint32_t WebRenderBridgeParent::sIdNameSpace = 0;
|
|
|
|
|
2017-01-11 15:51:27 +03:00
|
|
|
WebRenderBridgeParent::WebRenderBridgeParent(CompositorBridgeParentBase* aCompositorBridge,
|
2017-01-17 23:13:41 +03:00
|
|
|
const wr::PipelineId& aPipelineId,
|
2017-01-11 15:51:27 +03:00
|
|
|
widget::CompositorWidget* aWidget,
|
2017-02-27 03:27:04 +03:00
|
|
|
CompositorVsyncScheduler* aScheduler,
|
2017-01-20 05:00:17 +03:00
|
|
|
RefPtr<wr::WebRenderAPI>&& aApi,
|
2017-07-25 12:36:11 +03:00
|
|
|
RefPtr<WebRenderCompositableHolder>&& aHolder,
|
2017-06-15 10:36:03 +03:00
|
|
|
RefPtr<CompositorAnimationStorage>&& aAnimStorage)
|
2017-01-11 15:51:27 +03:00
|
|
|
: mCompositorBridge(aCompositorBridge)
|
|
|
|
, mPipelineId(aPipelineId)
|
|
|
|
, mWidget(aWidget)
|
|
|
|
, mApi(aApi)
|
2017-07-25 12:36:11 +03:00
|
|
|
, mCompositableHolder(aHolder)
|
2017-02-27 03:27:04 +03:00
|
|
|
, mCompositorScheduler(aScheduler)
|
2017-06-15 10:36:03 +03:00
|
|
|
, mAnimStorage(aAnimStorage)
|
2017-01-11 15:51:27 +03:00
|
|
|
, mChildLayerObserverEpoch(0)
|
|
|
|
, mParentLayerObserverEpoch(0)
|
2017-02-24 06:22:59 +03:00
|
|
|
, mWrEpoch(0)
|
2017-05-09 11:19:48 +03:00
|
|
|
, mIdNameSpace(AllocIdNameSpace())
|
2017-04-05 17:12:11 +03:00
|
|
|
, mPaused(false)
|
2017-01-11 15:51:27 +03:00
|
|
|
, mDestroyed(false)
|
2017-06-02 02:07:59 +03:00
|
|
|
, mForceRendering(false)
|
2017-01-11 15:51:27 +03:00
|
|
|
{
|
2017-07-25 12:36:11 +03:00
|
|
|
MOZ_ASSERT(mCompositableHolder);
|
2017-06-15 10:36:03 +03:00
|
|
|
MOZ_ASSERT(mAnimStorage);
|
2017-07-25 12:36:11 +03:00
|
|
|
mCompositableHolder->AddPipeline(mPipelineId);
|
2017-01-11 15:51:27 +03:00
|
|
|
if (mWidget) {
|
2017-02-27 03:27:04 +03:00
|
|
|
MOZ_ASSERT(!mCompositorScheduler);
|
2017-01-11 15:51:27 +03:00
|
|
|
mCompositorScheduler = new CompositorVsyncScheduler(this, mWidget);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-30 04:06:11 +03:00
|
|
|
WebRenderBridgeParent::WebRenderBridgeParent()
|
|
|
|
: mCompositorBridge(nullptr)
|
|
|
|
, mChildLayerObserverEpoch(0)
|
|
|
|
, mParentLayerObserverEpoch(0)
|
|
|
|
, mWrEpoch(0)
|
|
|
|
, mIdNameSpace(AllocIdNameSpace())
|
|
|
|
, mPaused(false)
|
|
|
|
, mDestroyed(true)
|
|
|
|
, mForceRendering(false)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
/* static */ WebRenderBridgeParent*
|
|
|
|
WebRenderBridgeParent::CeateDestroyed()
|
|
|
|
{
|
|
|
|
return new WebRenderBridgeParent();
|
|
|
|
}
|
|
|
|
|
2017-06-02 10:11:34 +03:00
|
|
|
WebRenderBridgeParent::~WebRenderBridgeParent()
|
|
|
|
{
|
|
|
|
}
|
2017-01-11 15:51:27 +03:00
|
|
|
|
2016-11-16 16:54:51 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2017-01-17 23:13:41 +03:00
|
|
|
WebRenderBridgeParent::RecvCreate(const gfx::IntSize& aSize)
|
2016-11-16 16:54:51 +03:00
|
|
|
{
|
2016-11-28 04:21:33 +03:00
|
|
|
if (mDestroyed) {
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2017-02-10 18:16:47 +03:00
|
|
|
MOZ_ASSERT(mApi);
|
2017-02-10 18:16:47 +03:00
|
|
|
|
2017-04-05 17:12:11 +03:00
|
|
|
#ifdef MOZ_WIDGET_ANDROID
|
|
|
|
// XXX temporary hack.
|
|
|
|
// XXX Remove it when APZ is supported.
|
2017-04-06 01:42:50 +03:00
|
|
|
// XXX Broken by Dynamic Toolbar v3. See: Bug 1335895
|
|
|
|
// RefPtr<UiCompositorControllerParent> uiController = UiCompositorControllerParent::GetFromRootLayerTreeId(/* Root Layer Tree ID */);
|
|
|
|
// if (uiController) {
|
|
|
|
// uiController->ToolbarAnimatorMessageFromCompositor(/*FIRST_PAINT*/ 5);
|
|
|
|
// }
|
2017-04-05 17:12:11 +03:00
|
|
|
#endif
|
|
|
|
|
2016-11-16 16:54:51 +03:00
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::ipc::IPCResult
|
2016-11-25 04:36:37 +03:00
|
|
|
WebRenderBridgeParent::RecvShutdown()
|
2017-06-29 21:46:36 +03:00
|
|
|
{
|
|
|
|
return HandleShutdown();
|
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::ipc::IPCResult
|
|
|
|
WebRenderBridgeParent::RecvShutdownSync()
|
|
|
|
{
|
|
|
|
return HandleShutdown();
|
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::ipc::IPCResult
|
|
|
|
WebRenderBridgeParent::HandleShutdown()
|
2016-11-16 16:54:51 +03:00
|
|
|
{
|
2016-11-28 04:21:33 +03:00
|
|
|
Destroy();
|
2017-05-18 03:31:46 +03:00
|
|
|
IProtocol* mgr = Manager();
|
2016-11-25 04:36:37 +03:00
|
|
|
if (!Send__delete__(this)) {
|
2017-05-18 03:31:46 +03:00
|
|
|
return IPC_FAIL_NO_REASON(mgr);
|
2016-11-25 04:36:37 +03:00
|
|
|
}
|
2016-11-16 16:54:51 +03:00
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2016-11-28 04:21:33 +03:00
|
|
|
void
|
|
|
|
WebRenderBridgeParent::Destroy()
|
|
|
|
{
|
|
|
|
if (mDestroyed) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
mDestroyed = true;
|
|
|
|
ClearResources();
|
|
|
|
}
|
|
|
|
|
2016-11-16 16:54:51 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2017-02-22 21:19:57 +03:00
|
|
|
WebRenderBridgeParent::RecvAddImage(const wr::ImageKey& aImageKey,
|
2017-03-27 14:44:52 +03:00
|
|
|
const gfx::IntSize& aSize,
|
2016-11-16 16:54:51 +03:00
|
|
|
const uint32_t& aStride,
|
2017-01-17 23:13:41 +03:00
|
|
|
const gfx::SurfaceFormat& aFormat,
|
2017-02-22 21:19:57 +03:00
|
|
|
const ByteBuffer& aBuffer)
|
2016-11-16 16:54:51 +03:00
|
|
|
{
|
2016-11-28 04:21:33 +03:00
|
|
|
if (mDestroyed) {
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
2017-06-30 04:06:11 +03:00
|
|
|
|
|
|
|
// Check if key is obsoleted.
|
|
|
|
if (aImageKey.mNamespace != mIdNameSpace) {
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2017-02-10 18:16:47 +03:00
|
|
|
MOZ_ASSERT(mApi);
|
2017-06-16 09:31:01 +03:00
|
|
|
MOZ_ASSERT(mActiveImageKeys.find(wr::AsUint64(aImageKey)) == mActiveImageKeys.end());
|
|
|
|
|
2017-02-14 21:34:15 +03:00
|
|
|
wr::ImageDescriptor descriptor(aSize, aStride, aFormat);
|
2017-06-16 09:31:01 +03:00
|
|
|
mActiveImageKeys.insert(wr::AsUint64(aImageKey));
|
2017-02-22 21:19:57 +03:00
|
|
|
mApi->AddImage(aImageKey, descriptor,
|
|
|
|
aBuffer.AsSlice());
|
2017-02-10 18:16:47 +03:00
|
|
|
|
2016-11-16 16:54:51 +03:00
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2017-03-27 14:44:52 +03:00
|
|
|
mozilla::ipc::IPCResult
|
|
|
|
WebRenderBridgeParent::RecvAddBlobImage(const wr::ImageKey& aImageKey,
|
2017-04-26 05:58:50 +03:00
|
|
|
const gfx::IntSize& aSize,
|
2017-03-27 14:44:52 +03:00
|
|
|
const uint32_t& aStride,
|
|
|
|
const gfx::SurfaceFormat& aFormat,
|
|
|
|
const ByteBuffer& aBuffer)
|
|
|
|
{
|
|
|
|
if (mDestroyed) {
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
2017-06-30 04:06:11 +03:00
|
|
|
|
|
|
|
// Check if key is obsoleted.
|
|
|
|
if (aImageKey.mNamespace != mIdNameSpace) {
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2017-03-27 14:44:52 +03:00
|
|
|
MOZ_ASSERT(mApi);
|
2017-06-16 09:31:01 +03:00
|
|
|
MOZ_ASSERT(mActiveImageKeys.find(wr::AsUint64(aImageKey)) == mActiveImageKeys.end());
|
|
|
|
|
2017-03-27 14:44:52 +03:00
|
|
|
wr::ImageDescriptor descriptor(aSize, aStride, aFormat);
|
2017-06-16 09:31:01 +03:00
|
|
|
mActiveImageKeys.insert(wr::AsUint64(aImageKey));
|
2017-03-27 14:44:52 +03:00
|
|
|
mApi->AddBlobImage(aImageKey, descriptor,
|
|
|
|
aBuffer.AsSlice());
|
|
|
|
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2017-02-22 21:19:57 +03:00
|
|
|
mozilla::ipc::IPCResult
|
|
|
|
WebRenderBridgeParent::RecvAddRawFont(const wr::FontKey& aFontKey,
|
|
|
|
const ByteBuffer& aBuffer,
|
|
|
|
const uint32_t& aFontIndex)
|
|
|
|
{
|
|
|
|
if (mDestroyed) {
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
2017-06-30 04:06:11 +03:00
|
|
|
|
|
|
|
// Check if key is obsoleted.
|
|
|
|
if (aFontKey.mNamespace != mIdNameSpace) {
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2017-02-22 21:19:57 +03:00
|
|
|
MOZ_ASSERT(mApi);
|
2017-06-16 09:31:01 +03:00
|
|
|
MOZ_ASSERT(mFontKeys.find(wr::AsUint64(aFontKey)) == mFontKeys.end());
|
|
|
|
|
2017-02-22 21:19:57 +03:00
|
|
|
auto slice = aBuffer.AsSlice();
|
2017-06-16 09:31:01 +03:00
|
|
|
mFontKeys.insert(wr::AsUint64(aFontKey));
|
2017-04-21 18:50:21 +03:00
|
|
|
mApi->AddRawFont(aFontKey, slice, aFontIndex);
|
2017-02-22 21:19:57 +03:00
|
|
|
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2017-04-07 00:41:24 +03:00
|
|
|
mozilla::ipc::IPCResult
|
|
|
|
WebRenderBridgeParent::RecvDeleteFont(const wr::FontKey& aFontKey)
|
|
|
|
{
|
|
|
|
if (mDestroyed) {
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
MOZ_ASSERT(mApi);
|
2017-06-16 09:31:01 +03:00
|
|
|
|
2017-06-30 04:06:11 +03:00
|
|
|
// Check if key is obsoleted.
|
|
|
|
if (aFontKey.mNamespace != mIdNameSpace) {
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2017-06-16 09:31:01 +03:00
|
|
|
if (mFontKeys.find(wr::AsUint64(aFontKey)) != mFontKeys.end()) {
|
|
|
|
mFontKeys.erase(wr::AsUint64(aFontKey));
|
|
|
|
mApi->DeleteFont(aFontKey);
|
|
|
|
} else {
|
|
|
|
MOZ_ASSERT_UNREACHABLE("invalid FontKey");
|
|
|
|
}
|
|
|
|
|
2017-04-07 00:41:24 +03:00
|
|
|
return IPC_OK();
|
|
|
|
}
|
2017-02-22 21:19:57 +03:00
|
|
|
|
2016-11-16 16:54:51 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2017-01-17 23:13:41 +03:00
|
|
|
WebRenderBridgeParent::RecvUpdateImage(const wr::ImageKey& aImageKey,
|
|
|
|
const gfx::IntSize& aSize,
|
|
|
|
const gfx::SurfaceFormat& aFormat,
|
2016-11-16 16:54:51 +03:00
|
|
|
const ByteBuffer& aBuffer)
|
|
|
|
{
|
2016-11-28 04:21:33 +03:00
|
|
|
if (mDestroyed) {
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
2017-02-10 18:16:47 +03:00
|
|
|
MOZ_ASSERT(mApi);
|
2017-06-30 04:06:11 +03:00
|
|
|
|
|
|
|
// Check if key is obsoleted.
|
|
|
|
if (aImageKey.mNamespace != mIdNameSpace) {
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2017-02-14 21:34:15 +03:00
|
|
|
wr::ImageDescriptor descriptor(aSize, aFormat);
|
|
|
|
mApi->UpdateImageBuffer(aImageKey, descriptor, aBuffer.AsSlice());
|
2017-02-10 18:16:47 +03:00
|
|
|
|
2016-11-16 16:54:51 +03:00
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::ipc::IPCResult
|
2017-01-17 23:13:41 +03:00
|
|
|
WebRenderBridgeParent::RecvDeleteImage(const wr::ImageKey& aImageKey)
|
2016-11-16 16:54:51 +03:00
|
|
|
{
|
2016-11-28 04:21:33 +03:00
|
|
|
if (mDestroyed) {
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
2017-02-10 18:16:47 +03:00
|
|
|
MOZ_ASSERT(mApi);
|
2017-06-30 04:06:11 +03:00
|
|
|
|
|
|
|
// Check if key is obsoleted.
|
|
|
|
if (aImageKey.mNamespace != mIdNameSpace) {
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2017-06-16 09:31:01 +03:00
|
|
|
if (mActiveImageKeys.find(wr::AsUint64(aImageKey)) != mActiveImageKeys.end()) {
|
|
|
|
mActiveImageKeys.erase(wr::AsUint64(aImageKey));
|
|
|
|
mKeysToDelete.push_back(aImageKey);
|
|
|
|
} else {
|
|
|
|
MOZ_ASSERT_UNREACHABLE("invalid ImageKey");
|
2017-04-13 14:53:21 +03:00
|
|
|
}
|
2016-11-16 16:54:51 +03:00
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2017-04-19 12:54:11 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2017-04-26 05:58:50 +03:00
|
|
|
WebRenderBridgeParent::RecvDeleteCompositorAnimations(InfallibleTArray<uint64_t>&& aIds)
|
2017-04-19 12:54:11 +03:00
|
|
|
{
|
|
|
|
if (mDestroyed) {
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2017-04-26 05:58:50 +03:00
|
|
|
for (uint32_t i = 0; i < aIds.Length(); i++) {
|
2017-06-15 10:36:03 +03:00
|
|
|
if (mActiveAnimations.find(aIds[i]) != mActiveAnimations.end()) {
|
|
|
|
mAnimStorage->ClearById(aIds[i]);
|
|
|
|
mActiveAnimations.erase(aIds[i]);
|
|
|
|
} else {
|
|
|
|
NS_ERROR("Tried to delete invalid animation");
|
|
|
|
}
|
2017-04-26 05:58:50 +03:00
|
|
|
}
|
2017-04-19 12:54:11 +03:00
|
|
|
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-11-16 16:54:51 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2017-02-21 04:30:15 +03:00
|
|
|
WebRenderBridgeParent::RecvDPBegin(const gfx::IntSize& aSize)
|
2016-11-16 16:54:51 +03:00
|
|
|
{
|
2016-11-28 04:21:33 +03:00
|
|
|
if (mDestroyed) {
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
2016-11-16 16:54:51 +03:00
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2016-12-30 00:51:32 +03:00
|
|
|
void
|
2017-02-24 00:12:40 +03:00
|
|
|
WebRenderBridgeParent::HandleDPEnd(const gfx::IntSize& aSize,
|
2017-03-03 00:33:03 +03:00
|
|
|
InfallibleTArray<WebRenderParentCommand>&& aCommands,
|
2016-12-05 07:15:02 +03:00
|
|
|
InfallibleTArray<OpDestroy>&& aToDestroy,
|
2016-12-07 13:02:04 +03:00
|
|
|
const uint64_t& aFwdTransactionId,
|
2017-03-02 04:36:27 +03:00
|
|
|
const uint64_t& aTransactionId,
|
2017-07-19 01:32:46 +03:00
|
|
|
const wr::LayoutSize& aContentSize,
|
2017-06-28 02:20:36 +03:00
|
|
|
const wr::ByteBuffer& dl,
|
2017-07-19 10:28:58 +03:00
|
|
|
const wr::BuiltDisplayListDescriptor& dlDesc,
|
2017-06-30 04:06:11 +03:00
|
|
|
const WebRenderScrollData& aScrollData,
|
|
|
|
const uint32_t& aIdNameSpace)
|
2016-11-21 18:16:11 +03:00
|
|
|
{
|
2017-06-07 05:33:19 +03:00
|
|
|
AutoProfilerTracing tracing("Paint", "DPTransaction");
|
2016-12-07 13:02:04 +03:00
|
|
|
UpdateFwdTransactionId(aFwdTransactionId);
|
2017-02-27 06:12:12 +03:00
|
|
|
AutoClearReadLocks clearLocks(mReadLocks);
|
2016-12-07 13:02:04 +03:00
|
|
|
|
2016-11-28 04:21:33 +03:00
|
|
|
if (mDestroyed) {
|
2016-12-05 07:15:02 +03:00
|
|
|
for (const auto& op : aToDestroy) {
|
|
|
|
DestroyActor(op);
|
|
|
|
}
|
2016-12-30 00:51:32 +03:00
|
|
|
return;
|
2016-11-28 04:21:33 +03:00
|
|
|
}
|
2016-12-07 13:02:04 +03:00
|
|
|
// This ensures that destroy operations are always processed. It is not safe
|
|
|
|
// to early-return from RecvDPEnd without doing so.
|
|
|
|
AutoWebRenderBridgeParentAsyncMessageSender autoAsyncMessageSender(this, &aToDestroy);
|
|
|
|
|
2017-07-24 15:20:22 +03:00
|
|
|
uint32_t wrEpoch = GetNextWrEpoch();
|
|
|
|
ProcessWebRenderCommands(aSize, aCommands, wr::NewEpoch(wrEpoch),
|
2017-06-30 04:06:11 +03:00
|
|
|
aContentSize, dl, dlDesc, aIdNameSpace);
|
2017-07-24 15:20:22 +03:00
|
|
|
HoldPendingTransactionId(wrEpoch, aTransactionId);
|
2017-04-20 17:38:04 +03:00
|
|
|
|
2017-04-20 17:38:06 +03:00
|
|
|
mScrollData = aScrollData;
|
2017-04-20 17:38:06 +03:00
|
|
|
UpdateAPZ();
|
2017-06-30 04:06:31 +03:00
|
|
|
|
|
|
|
if (mIdNameSpace != aIdNameSpace) {
|
|
|
|
// Pretend we composited since someone is wating for this event,
|
|
|
|
// though DisplayList was not pushed to webrender.
|
|
|
|
TimeStamp now = TimeStamp::Now();
|
|
|
|
mCompositorBridge->DidComposite(wr::AsUint64(mPipelineId), now, now);
|
|
|
|
}
|
2017-04-20 17:38:06 +03:00
|
|
|
}
|
|
|
|
|
2017-05-12 20:58:17 +03:00
|
|
|
CompositorBridgeParent*
|
|
|
|
WebRenderBridgeParent::GetRootCompositorBridgeParent() const
|
2017-04-20 17:38:06 +03:00
|
|
|
{
|
|
|
|
if (!mCompositorBridge) {
|
2017-05-12 20:58:17 +03:00
|
|
|
return nullptr;
|
2017-04-20 17:38:06 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
if (mWidget) {
|
|
|
|
// This WebRenderBridgeParent is attached to the root
|
|
|
|
// CompositorBridgeParent.
|
2017-05-12 20:58:17 +03:00
|
|
|
return static_cast<CompositorBridgeParent*>(mCompositorBridge);
|
2017-04-20 17:38:06 +03:00
|
|
|
}
|
|
|
|
|
2017-05-12 20:58:17 +03:00
|
|
|
// Otherwise, this WebRenderBridgeParent is attached to a
|
|
|
|
// CrossProcessCompositorBridgeParent so we have an extra level of
|
|
|
|
// indirection to unravel.
|
|
|
|
CompositorBridgeParent::LayerTreeState* lts =
|
2017-05-28 14:51:53 +03:00
|
|
|
CompositorBridgeParent::GetIndirectShadowTree(GetLayersId());
|
2017-05-12 20:58:17 +03:00
|
|
|
MOZ_ASSERT(lts);
|
|
|
|
return lts->mParent;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
WebRenderBridgeParent::UpdateAPZ()
|
|
|
|
{
|
|
|
|
CompositorBridgeParent* cbp = GetRootCompositorBridgeParent();
|
|
|
|
if (!cbp) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
uint64_t rootLayersId = cbp->RootLayerTreeId();
|
|
|
|
RefPtr<WebRenderBridgeParent> rootWrbp = cbp->GetWebRenderBridgeParent();
|
2017-04-20 17:38:06 +03:00
|
|
|
if (!rootWrbp) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (RefPtr<APZCTreeManager> apzc = cbp->GetAPZCTreeManager()) {
|
2017-06-13 09:43:59 +03:00
|
|
|
apzc->UpdateFocusState(rootLayersId, GetLayersId(),
|
2017-06-29 03:00:48 +03:00
|
|
|
mScrollData.GetFocusTarget());
|
2017-04-20 17:38:06 +03:00
|
|
|
apzc->UpdateHitTestingTree(rootLayersId, rootWrbp->GetScrollData(),
|
2017-05-28 14:51:53 +03:00
|
|
|
mScrollData.IsFirstPaint(), GetLayersId(),
|
2017-06-05 05:29:35 +03:00
|
|
|
mScrollData.GetPaintSequenceNumber());
|
2017-04-20 17:38:06 +03:00
|
|
|
}
|
2016-12-30 00:51:32 +03:00
|
|
|
}
|
|
|
|
|
2017-05-12 20:58:20 +03:00
|
|
|
bool
|
2017-06-28 02:20:36 +03:00
|
|
|
WebRenderBridgeParent::PushAPZStateToWR(nsTArray<wr::WrTransformProperty>& aTransformArray)
|
2017-05-12 20:58:20 +03:00
|
|
|
{
|
|
|
|
CompositorBridgeParent* cbp = GetRootCompositorBridgeParent();
|
|
|
|
if (!cbp) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (RefPtr<APZCTreeManager> apzc = cbp->GetAPZCTreeManager()) {
|
2017-06-28 03:29:05 +03:00
|
|
|
TimeStamp animationTime = cbp->GetTestingTimeStamp().valueOr(
|
|
|
|
mCompositorScheduler->GetLastComposeTime());
|
2017-05-12 20:58:20 +03:00
|
|
|
TimeDuration frameInterval = cbp->GetVsyncInterval();
|
|
|
|
// As with the non-webrender codepath in AsyncCompositionManager, we want to
|
|
|
|
// use the timestamp for the next vsync when advancing animations.
|
|
|
|
if (frameInterval != TimeDuration::Forever()) {
|
|
|
|
animationTime += frameInterval;
|
|
|
|
}
|
2017-05-23 17:50:42 +03:00
|
|
|
return apzc->PushStateToWR(mApi, animationTime, aTransformArray);
|
2017-05-12 20:58:20 +03:00
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2017-04-20 17:38:06 +03:00
|
|
|
const WebRenderScrollData&
|
|
|
|
WebRenderBridgeParent::GetScrollData() const
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(mozilla::layers::CompositorThreadHolder::IsInCompositorThread());
|
|
|
|
return mScrollData;
|
|
|
|
}
|
|
|
|
|
2016-12-30 00:51:32 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2017-02-24 00:12:40 +03:00
|
|
|
WebRenderBridgeParent::RecvDPEnd(const gfx::IntSize& aSize,
|
2017-03-03 00:33:03 +03:00
|
|
|
InfallibleTArray<WebRenderParentCommand>&& aCommands,
|
2016-12-30 00:51:32 +03:00
|
|
|
InfallibleTArray<OpDestroy>&& aToDestroy,
|
|
|
|
const uint64_t& aFwdTransactionId,
|
2017-03-02 04:36:27 +03:00
|
|
|
const uint64_t& aTransactionId,
|
2017-07-19 01:32:46 +03:00
|
|
|
const wr::LayoutSize& aContentSize,
|
2017-06-28 02:20:36 +03:00
|
|
|
const wr::ByteBuffer& dl,
|
2017-07-19 10:28:58 +03:00
|
|
|
const wr::BuiltDisplayListDescriptor& dlDesc,
|
2017-06-30 04:06:11 +03:00
|
|
|
const WebRenderScrollData& aScrollData,
|
|
|
|
const uint32_t& aIdNameSpace)
|
2017-03-02 04:36:27 +03:00
|
|
|
{
|
2017-06-05 09:41:21 +03:00
|
|
|
if (mDestroyed) {
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
2017-03-02 04:36:27 +03:00
|
|
|
HandleDPEnd(aSize, Move(aCommands), Move(aToDestroy), aFwdTransactionId, aTransactionId,
|
2017-06-30 04:06:11 +03:00
|
|
|
aContentSize, dl, dlDesc, aScrollData, aIdNameSpace);
|
2016-11-21 18:16:11 +03:00
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::ipc::IPCResult
|
2017-02-24 00:12:40 +03:00
|
|
|
WebRenderBridgeParent::RecvDPSyncEnd(const gfx::IntSize &aSize,
|
2017-03-03 00:33:03 +03:00
|
|
|
InfallibleTArray<WebRenderParentCommand>&& aCommands,
|
2016-12-05 07:15:02 +03:00
|
|
|
InfallibleTArray<OpDestroy>&& aToDestroy,
|
2016-12-07 13:02:04 +03:00
|
|
|
const uint64_t& aFwdTransactionId,
|
2017-03-02 04:36:27 +03:00
|
|
|
const uint64_t& aTransactionId,
|
2017-07-19 01:32:46 +03:00
|
|
|
const wr::LayoutSize& aContentSize,
|
2017-06-28 02:20:36 +03:00
|
|
|
const wr::ByteBuffer& dl,
|
2017-07-19 10:28:58 +03:00
|
|
|
const wr::BuiltDisplayListDescriptor& dlDesc,
|
2017-06-30 04:06:11 +03:00
|
|
|
const WebRenderScrollData& aScrollData,
|
|
|
|
const uint32_t& aIdNameSpace)
|
2017-03-02 04:36:27 +03:00
|
|
|
{
|
2017-06-05 09:41:21 +03:00
|
|
|
if (mDestroyed) {
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
2017-03-02 04:36:27 +03:00
|
|
|
HandleDPEnd(aSize, Move(aCommands), Move(aToDestroy), aFwdTransactionId, aTransactionId,
|
2017-06-30 04:06:11 +03:00
|
|
|
aContentSize, dl, dlDesc, aScrollData, aIdNameSpace);
|
2016-12-30 00:51:32 +03:00
|
|
|
return IPC_OK();
|
2016-11-21 18:16:11 +03:00
|
|
|
}
|
|
|
|
|
2017-06-15 07:38:22 +03:00
|
|
|
mozilla::ipc::IPCResult
|
|
|
|
WebRenderBridgeParent::RecvParentCommands(nsTArray<WebRenderParentCommand>&& aCommands)
|
2016-11-16 16:54:51 +03:00
|
|
|
{
|
2017-06-15 07:38:22 +03:00
|
|
|
if (mDestroyed) {
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
ProcessWebRenderParentCommands(aCommands);
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
2016-12-05 07:15:02 +03:00
|
|
|
|
2017-06-15 07:38:22 +03:00
|
|
|
void
|
|
|
|
WebRenderBridgeParent::ProcessWebRenderParentCommands(InfallibleTArray<WebRenderParentCommand>& aCommands)
|
|
|
|
{
|
2017-03-03 00:33:03 +03:00
|
|
|
for (InfallibleTArray<WebRenderParentCommand>::index_type i = 0; i < aCommands.Length(); ++i) {
|
|
|
|
const WebRenderParentCommand& cmd = aCommands[i];
|
2016-11-18 11:07:02 +03:00
|
|
|
switch (cmd.type()) {
|
2017-03-03 00:33:03 +03:00
|
|
|
case WebRenderParentCommand::TOpAddExternalImage: {
|
2017-02-22 21:19:57 +03:00
|
|
|
const OpAddExternalImage& op = cmd.get_OpAddExternalImage();
|
2017-05-18 19:25:42 +03:00
|
|
|
Range<const wr::ImageKey> keys(&op.key(), 1);
|
2017-06-30 04:06:11 +03:00
|
|
|
// Check if key is obsoleted.
|
|
|
|
if (keys[0].mNamespace != mIdNameSpace) {
|
|
|
|
break;
|
|
|
|
}
|
2017-04-19 12:59:53 +03:00
|
|
|
MOZ_ASSERT(mExternalImageIds.Get(wr::AsUint64(op.externalImageId())).get());
|
2017-06-16 09:31:01 +03:00
|
|
|
MOZ_ASSERT(mActiveImageKeys.find(wr::AsUint64(keys[0])) == mActiveImageKeys.end());
|
|
|
|
mActiveImageKeys.insert(wr::AsUint64(keys[0]));
|
2016-12-08 04:52:24 +03:00
|
|
|
|
2017-04-27 19:34:54 +03:00
|
|
|
RefPtr<WebRenderImageHost> host = mExternalImageIds.Get(wr::AsUint64(op.externalImageId()));
|
2016-12-22 18:38:58 +03:00
|
|
|
if (!host) {
|
2017-03-07 13:37:28 +03:00
|
|
|
NS_ERROR("CompositableHost does not exist");
|
|
|
|
break;
|
|
|
|
}
|
2017-07-17 08:38:22 +03:00
|
|
|
if (!gfxEnv::EnableWebRenderRecording()) {
|
|
|
|
TextureHost* texture = host->GetAsTextureHostForComposite();
|
|
|
|
if (!texture) {
|
|
|
|
NS_ERROR("TextureHost does not exist");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
WebRenderTextureHost* wrTexture = texture->AsWebRenderTextureHost();
|
|
|
|
if (wrTexture) {
|
|
|
|
wrTexture->AddWRImage(mApi, keys, wrTexture->GetExternalImageKey());
|
|
|
|
break;
|
|
|
|
}
|
2016-12-22 18:38:58 +03:00
|
|
|
}
|
|
|
|
RefPtr<DataSourceSurface> dSurf = host->GetAsSurface();
|
|
|
|
if (!dSurf) {
|
2017-06-02 10:11:34 +03:00
|
|
|
NS_ERROR("TextureHost does not return DataSourceSurface");
|
2016-12-22 18:38:58 +03:00
|
|
|
break;
|
|
|
|
}
|
2017-01-15 01:32:01 +03:00
|
|
|
|
2016-12-22 18:38:58 +03:00
|
|
|
DataSourceSurface::MappedSurface map;
|
2017-01-12 20:33:49 +03:00
|
|
|
if (!dSurf->Map(gfx::DataSourceSurface::MapType::READ, &map)) {
|
2017-06-02 10:11:34 +03:00
|
|
|
NS_ERROR("DataSourceSurface failed to map");
|
2016-12-05 07:15:02 +03:00
|
|
|
break;
|
|
|
|
}
|
2017-01-19 02:46:21 +03:00
|
|
|
|
2017-03-01 09:11:13 +03:00
|
|
|
IntSize size = dSurf->GetSize();
|
2017-03-10 12:51:47 +03:00
|
|
|
wr::ImageDescriptor descriptor(size, map.mStride, dSurf->GetFormat());
|
2017-03-01 09:11:13 +03:00
|
|
|
auto slice = Range<uint8_t>(map.mData, size.height * map.mStride);
|
2017-05-18 19:25:42 +03:00
|
|
|
mApi->AddImage(keys[0], descriptor, slice);
|
|
|
|
|
|
|
|
dSurf->Unmap();
|
|
|
|
break;
|
|
|
|
}
|
2017-06-02 10:11:34 +03:00
|
|
|
case WebRenderParentCommand::TOpUpdateAsyncImagePipeline: {
|
|
|
|
const OpUpdateAsyncImagePipeline& op = cmd.get_OpUpdateAsyncImagePipeline();
|
2017-07-25 12:36:11 +03:00
|
|
|
mCompositableHolder->UpdateAsyncImagePipeline(op.pipelineId(),
|
2017-06-02 10:11:34 +03:00
|
|
|
op.scBounds(),
|
|
|
|
op.scTransform(),
|
|
|
|
op.scaleToSize(),
|
|
|
|
op.filter(),
|
|
|
|
op.mixBlendMode());
|
2016-12-05 07:15:02 +03:00
|
|
|
break;
|
|
|
|
}
|
2017-03-03 00:33:03 +03:00
|
|
|
case WebRenderParentCommand::TCompositableOperation: {
|
2016-12-07 02:34:54 +03:00
|
|
|
if (!ReceiveCompositableUpdate(cmd.get_CompositableOperation())) {
|
2016-12-05 07:15:02 +03:00
|
|
|
NS_ERROR("ReceiveCompositableUpdate failed");
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2017-03-28 12:11:03 +03:00
|
|
|
case WebRenderParentCommand::TOpAddCompositorAnimations: {
|
|
|
|
const OpAddCompositorAnimations& op = cmd.get_OpAddCompositorAnimations();
|
|
|
|
CompositorAnimations data(Move(op.data()));
|
|
|
|
if (data.animations().Length()) {
|
2017-06-15 10:36:03 +03:00
|
|
|
mAnimStorage->SetAnimations(data.id(), data.animations());
|
|
|
|
mActiveAnimations.insert(data.id());
|
|
|
|
// Store the default opacity
|
|
|
|
if (op.opacity().type() == OptionalOpacity::Tfloat) {
|
|
|
|
mAnimStorage->SetAnimatedValue(data.id(), op.opacity().get_float());
|
|
|
|
}
|
|
|
|
// Store the default transform
|
|
|
|
if (op.transform().type() == OptionalTransform::TMatrix4x4) {
|
|
|
|
Matrix4x4 transform(Move(op.transform().get_Matrix4x4()));
|
|
|
|
mAnimStorage->SetAnimatedValue(data.id(), Move(transform));
|
2017-03-28 12:11:03 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2017-03-02 04:36:27 +03:00
|
|
|
default: {
|
|
|
|
// other commands are handle on the child
|
2017-02-16 21:23:22 +03:00
|
|
|
break;
|
|
|
|
}
|
2016-11-18 11:07:02 +03:00
|
|
|
}
|
|
|
|
}
|
2017-06-15 07:38:22 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
WebRenderBridgeParent::ProcessWebRenderCommands(const gfx::IntSize &aSize,
|
|
|
|
InfallibleTArray<WebRenderParentCommand>& aCommands, const wr::Epoch& aEpoch,
|
2017-07-19 01:32:46 +03:00
|
|
|
const wr::LayoutSize& aContentSize, const wr::ByteBuffer& dl,
|
2017-07-19 10:28:58 +03:00
|
|
|
const wr::BuiltDisplayListDescriptor& dlDesc,
|
2017-06-30 04:06:11 +03:00
|
|
|
const uint32_t& aIdNameSpace)
|
2017-06-15 07:38:22 +03:00
|
|
|
{
|
2017-07-25 12:36:11 +03:00
|
|
|
mCompositableHolder->SetCompositionTime(TimeStamp::Now());
|
2017-06-15 07:38:22 +03:00
|
|
|
ProcessWebRenderParentCommands(aCommands);
|
|
|
|
|
2017-06-30 04:06:11 +03:00
|
|
|
// The command is obsoleted.
|
|
|
|
// Do not set the command to webrender since it causes crash in webrender.
|
|
|
|
if (mIdNameSpace != aIdNameSpace) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-03-07 01:41:51 +03:00
|
|
|
if (mWidget) {
|
|
|
|
LayoutDeviceIntSize size = mWidget->GetClientSize();
|
|
|
|
mApi->SetWindowParameters(size);
|
|
|
|
}
|
2017-06-01 14:42:55 +03:00
|
|
|
gfx::Color color = mWidget ? gfx::Color(0.3f, 0.f, 0.f, 1.f) : gfx::Color(0.f, 0.f, 0.f, 0.f);
|
|
|
|
mApi->SetRootDisplayList(color, aEpoch, LayerSize(aSize.width, aSize.height),
|
2017-05-15 22:13:31 +03:00
|
|
|
mPipelineId, aContentSize,
|
2017-05-08 20:52:16 +03:00
|
|
|
dlDesc, dl.mData, dl.mLength);
|
2017-01-19 02:46:21 +03:00
|
|
|
|
2016-11-22 05:56:38 +03:00
|
|
|
ScheduleComposition();
|
2016-12-22 18:38:58 +03:00
|
|
|
DeleteOldImages();
|
|
|
|
|
2016-11-30 05:59:14 +03:00
|
|
|
if (ShouldParentObserveEpoch()) {
|
2017-05-28 14:51:53 +03:00
|
|
|
mCompositorBridge->ObserveLayerUpdate(GetLayersId(), GetChildLayerObserverEpoch(), true);
|
2016-11-30 05:59:14 +03:00
|
|
|
}
|
2016-11-19 03:10:53 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::ipc::IPCResult
|
2016-12-13 00:41:15 +03:00
|
|
|
WebRenderBridgeParent::RecvDPGetSnapshot(PTextureParent* aTexture)
|
2016-11-19 03:10:53 +03:00
|
|
|
{
|
2016-11-28 04:21:33 +03:00
|
|
|
if (mDestroyed) {
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
2017-04-05 17:12:11 +03:00
|
|
|
MOZ_ASSERT(!mPaused);
|
2016-11-28 05:39:42 +03:00
|
|
|
|
|
|
|
RefPtr<TextureHost> texture = TextureHost::AsTextureHost(aTexture);
|
|
|
|
if (!texture) {
|
|
|
|
// We kill the content process rather than have it continue with an invalid
|
|
|
|
// snapshot, that may be too harsh and we could decide to return some sort
|
|
|
|
// of error to the child process and let it deal with it...
|
|
|
|
return IPC_FAIL_NO_REASON(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
// XXX Add other TextureHost supports.
|
|
|
|
// Only BufferTextureHost is supported now.
|
|
|
|
BufferTextureHost* bufferTexture = texture->AsBufferTextureHost();
|
|
|
|
if (!bufferTexture) {
|
|
|
|
// We kill the content process rather than have it continue with an invalid
|
|
|
|
// snapshot, that may be too harsh and we could decide to return some sort
|
|
|
|
// of error to the child process and let it deal with it...
|
|
|
|
return IPC_FAIL_NO_REASON(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
MOZ_ASSERT(bufferTexture->GetBufferDescriptor().type() == BufferDescriptor::TRGBDescriptor);
|
2016-12-04 11:53:28 +03:00
|
|
|
DebugOnly<uint32_t> stride = ImageDataSerializer::GetRGBStride(bufferTexture->GetBufferDescriptor().get_RGBDescriptor());
|
2016-12-02 21:39:40 +03:00
|
|
|
uint8_t* buffer = bufferTexture->GetBuffer();
|
|
|
|
IntSize size = bufferTexture->GetSize();
|
2016-11-28 05:39:42 +03:00
|
|
|
|
2016-12-02 21:39:40 +03:00
|
|
|
// We only support B8G8R8A8 for now.
|
|
|
|
MOZ_ASSERT(buffer);
|
|
|
|
MOZ_ASSERT(bufferTexture->GetFormat() == SurfaceFormat::B8G8R8A8);
|
|
|
|
uint32_t buffer_size = size.width * size.height * 4;
|
2016-11-19 03:10:53 +03:00
|
|
|
|
2016-12-10 12:30:49 +03:00
|
|
|
// Assert the stride of the buffer is what webrender expects
|
2016-12-02 21:39:40 +03:00
|
|
|
MOZ_ASSERT((uint32_t)(size.width * 4) == stride);
|
2016-11-19 03:10:53 +03:00
|
|
|
|
2017-06-02 02:07:59 +03:00
|
|
|
mForceRendering = true;
|
2017-05-19 03:21:38 +03:00
|
|
|
|
2017-02-27 03:27:04 +03:00
|
|
|
if (mCompositorScheduler->NeedsComposite()) {
|
|
|
|
mCompositorScheduler->CancelCurrentCompositeTask();
|
|
|
|
mCompositorScheduler->ForceComposeToTarget(nullptr, nullptr);
|
|
|
|
}
|
|
|
|
|
2017-02-10 18:16:47 +03:00
|
|
|
mApi->Readback(size, buffer, buffer_size);
|
2016-11-19 03:10:53 +03:00
|
|
|
|
2017-06-02 02:07:59 +03:00
|
|
|
mForceRendering = false;
|
2017-05-19 03:21:38 +03:00
|
|
|
|
2016-11-18 16:56:47 +03:00
|
|
|
return IPC_OK();
|
2016-11-16 16:54:51 +03:00
|
|
|
}
|
|
|
|
|
2016-11-24 09:48:01 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2017-06-02 10:11:34 +03:00
|
|
|
WebRenderBridgeParent::RecvAddPipelineIdForAsyncCompositable(const wr::PipelineId& aPipelineId,
|
|
|
|
const CompositableHandle& aHandle)
|
2016-11-24 09:48:01 +03:00
|
|
|
{
|
2016-11-28 04:21:33 +03:00
|
|
|
if (mDestroyed) {
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
2017-01-19 02:46:21 +03:00
|
|
|
|
2017-06-02 10:11:34 +03:00
|
|
|
MOZ_ASSERT(!mAsyncCompositables.Get(wr::AsUint64(aPipelineId)).get());
|
2016-11-24 09:48:01 +03:00
|
|
|
|
2017-05-31 03:11:53 +03:00
|
|
|
RefPtr<ImageBridgeParent> imageBridge = ImageBridgeParent::GetInstance(OtherPid());
|
2017-01-05 18:03:17 +03:00
|
|
|
if (!imageBridge) {
|
|
|
|
return IPC_FAIL_NO_REASON(this);
|
|
|
|
}
|
2017-01-18 21:47:27 +03:00
|
|
|
RefPtr<CompositableHost> host = imageBridge->FindCompositable(aHandle);
|
2017-01-05 18:03:17 +03:00
|
|
|
if (!host) {
|
|
|
|
return IPC_FAIL_NO_REASON(this);
|
2016-11-24 09:48:01 +03:00
|
|
|
}
|
2017-04-12 04:42:33 +03:00
|
|
|
MOZ_ASSERT(host->AsWebRenderImageHost());
|
2017-04-27 19:34:54 +03:00
|
|
|
WebRenderImageHost* wrHost = host->AsWebRenderImageHost();
|
|
|
|
if (!wrHost) {
|
2016-11-24 09:48:01 +03:00
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2017-05-16 08:18:54 +03:00
|
|
|
wrHost->SetWrBridge(this);
|
2017-06-02 10:11:34 +03:00
|
|
|
mAsyncCompositables.Put(wr::AsUint64(aPipelineId), wrHost);
|
2017-07-25 12:36:11 +03:00
|
|
|
mCompositableHolder->AddAsyncImagePipeline(aPipelineId, wrHost);
|
2017-02-10 18:16:47 +03:00
|
|
|
|
2016-12-08 04:52:24 +03:00
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2017-06-02 10:11:34 +03:00
|
|
|
mozilla::ipc::IPCResult
|
|
|
|
WebRenderBridgeParent::RecvRemovePipelineIdForAsyncCompositable(const wr::PipelineId& aPipelineId)
|
|
|
|
{
|
|
|
|
if (mDestroyed) {
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
|
|
|
WebRenderImageHost* wrHost = mAsyncCompositables.Get(wr::AsUint64(aPipelineId)).get();
|
2017-06-30 04:06:11 +03:00
|
|
|
if (!wrHost) {
|
|
|
|
return IPC_OK();
|
2017-06-02 10:11:34 +03:00
|
|
|
}
|
2017-06-30 04:06:11 +03:00
|
|
|
|
|
|
|
wrHost->ClearWrBridge();
|
2017-07-25 12:36:11 +03:00
|
|
|
mCompositableHolder->RemoveAsyncImagePipeline(mApi, aPipelineId);
|
2017-06-02 10:11:34 +03:00
|
|
|
mAsyncCompositables.Remove(wr::AsUint64(aPipelineId));
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2016-12-08 04:52:24 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2017-04-19 12:59:53 +03:00
|
|
|
WebRenderBridgeParent::RecvAddExternalImageIdForCompositable(const ExternalImageId& aImageId,
|
2017-01-18 21:47:27 +03:00
|
|
|
const CompositableHandle& aHandle)
|
2016-12-08 04:52:24 +03:00
|
|
|
{
|
|
|
|
if (mDestroyed) {
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
2017-04-19 12:59:53 +03:00
|
|
|
MOZ_ASSERT(!mExternalImageIds.Get(wr::AsUint64(aImageId)).get());
|
2016-12-08 04:52:24 +03:00
|
|
|
|
2017-01-18 21:47:27 +03:00
|
|
|
RefPtr<CompositableHost> host = FindCompositable(aHandle);
|
2017-04-12 04:42:33 +03:00
|
|
|
MOZ_ASSERT(host->AsWebRenderImageHost());
|
2017-04-27 19:34:54 +03:00
|
|
|
WebRenderImageHost* wrHost = host->AsWebRenderImageHost();
|
|
|
|
if (!wrHost) {
|
2016-12-08 04:52:24 +03:00
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2017-05-16 08:18:54 +03:00
|
|
|
wrHost->SetWrBridge(this);
|
2017-04-27 19:34:54 +03:00
|
|
|
mExternalImageIds.Put(wr::AsUint64(aImageId), wrHost);
|
2017-02-10 18:16:47 +03:00
|
|
|
|
2016-11-24 09:48:01 +03:00
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::ipc::IPCResult
|
2017-04-19 12:59:53 +03:00
|
|
|
WebRenderBridgeParent::RecvRemoveExternalImageId(const ExternalImageId& aImageId)
|
2016-11-24 09:48:01 +03:00
|
|
|
{
|
2016-11-28 04:21:33 +03:00
|
|
|
if (mDestroyed) {
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
2017-04-27 19:34:54 +03:00
|
|
|
WebRenderImageHost* wrHost = mExternalImageIds.Get(wr::AsUint64(aImageId)).get();
|
2017-06-30 04:06:11 +03:00
|
|
|
if (!wrHost) {
|
|
|
|
return IPC_OK();
|
2017-04-27 19:34:54 +03:00
|
|
|
}
|
2017-06-30 04:06:11 +03:00
|
|
|
|
|
|
|
wrHost->ClearWrBridge();
|
2017-04-19 12:59:53 +03:00
|
|
|
mExternalImageIds.Remove(wr::AsUint64(aImageId));
|
2017-02-10 18:16:47 +03:00
|
|
|
|
2016-11-24 09:48:01 +03:00
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2016-11-30 05:59:14 +03:00
|
|
|
mozilla::ipc::IPCResult
|
|
|
|
WebRenderBridgeParent::RecvSetLayerObserverEpoch(const uint64_t& aLayerObserverEpoch)
|
|
|
|
{
|
2017-06-05 09:41:21 +03:00
|
|
|
if (mDestroyed) {
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
2016-11-30 05:59:14 +03:00
|
|
|
mChildLayerObserverEpoch = aLayerObserverEpoch;
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::ipc::IPCResult
|
|
|
|
WebRenderBridgeParent::RecvClearCachedResources()
|
|
|
|
{
|
2017-06-05 09:41:21 +03:00
|
|
|
if (mDestroyed) {
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
2017-05-28 14:51:53 +03:00
|
|
|
mCompositorBridge->ObserveLayerUpdate(GetLayersId(), GetChildLayerObserverEpoch(), false);
|
2017-07-11 03:13:15 +03:00
|
|
|
|
|
|
|
// Clear resources
|
2017-07-24 15:20:22 +03:00
|
|
|
mApi->ClearRootDisplayList(wr::NewEpoch(GetNextWrEpoch()), mPipelineId);
|
2017-07-11 03:13:15 +03:00
|
|
|
// Schedule composition to clean up Pipeline
|
|
|
|
mCompositorScheduler->ScheduleComposition();
|
2017-07-20 04:30:31 +03:00
|
|
|
DeleteOldImages();
|
2017-07-11 03:13:15 +03:00
|
|
|
// Remove animations.
|
|
|
|
for (std::unordered_set<uint64_t>::iterator iter = mActiveAnimations.begin(); iter != mActiveAnimations.end(); iter++) {
|
|
|
|
mAnimStorage->ClearById(*iter);
|
|
|
|
}
|
|
|
|
mActiveAnimations.clear();
|
2016-11-30 05:59:14 +03:00
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2017-06-30 04:06:11 +03:00
|
|
|
void
|
|
|
|
WebRenderBridgeParent::UpdateWebRender(CompositorVsyncScheduler* aScheduler,
|
|
|
|
wr::WebRenderAPI* aApi,
|
2017-07-25 12:36:11 +03:00
|
|
|
WebRenderCompositableHolder* aHolder,
|
2017-06-30 04:06:11 +03:00
|
|
|
CompositorAnimationStorage* aAnimStorage)
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(!mWidget);
|
|
|
|
MOZ_ASSERT(aScheduler);
|
|
|
|
MOZ_ASSERT(aApi);
|
2017-07-25 12:36:11 +03:00
|
|
|
MOZ_ASSERT(aHolder);
|
2017-06-30 04:06:11 +03:00
|
|
|
MOZ_ASSERT(aAnimStorage);
|
|
|
|
|
|
|
|
if (mDestroyed) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Update id name space to identify obsoleted keys.
|
|
|
|
// Since usage of invalid keys could cause crash in webrender.
|
|
|
|
mIdNameSpace = AllocIdNameSpace();
|
|
|
|
// XXX Remove it when webrender supports sharing/moving Keys between different webrender instances.
|
|
|
|
// XXX It requests client to update/reallocate webrender related resources,
|
|
|
|
// but parent side does not wait end of the update.
|
|
|
|
// The code could become simpler if we could serialise old keys deallocation and new keys allocation.
|
|
|
|
// But we do not do it, it is because client side deallocate old layers/webrender keys
|
|
|
|
// after new layers/webrender keys allocation.
|
|
|
|
// Without client side's layout refactoring, we could not finish all old layers/webrender keys removals
|
|
|
|
// before new layer/webrender keys allocation. In future, we could address the problem.
|
|
|
|
Unused << SendWrUpdated(mIdNameSpace);
|
|
|
|
CompositorBridgeParentBase* cBridge = mCompositorBridge;
|
|
|
|
// XXX Stop to clear resources if webreder supports resources sharing between different webrender instances.
|
|
|
|
ClearResources();
|
|
|
|
mCompositorBridge = cBridge;
|
|
|
|
mCompositorScheduler = aScheduler;
|
|
|
|
mApi = aApi;
|
2017-07-25 12:36:11 +03:00
|
|
|
mCompositableHolder = aHolder;
|
2017-06-30 04:06:11 +03:00
|
|
|
mAnimStorage = aAnimStorage;
|
|
|
|
|
2017-07-24 15:20:22 +03:00
|
|
|
Unused << GetNextWrEpoch(); // Update webrender epoch
|
2017-07-25 12:36:11 +03:00
|
|
|
// Register pipeline to updated CompositableHolder.
|
|
|
|
mCompositableHolder->AddPipeline(mPipelineId);
|
2017-06-30 04:06:11 +03:00
|
|
|
}
|
|
|
|
|
2017-04-10 09:58:29 +03:00
|
|
|
mozilla::ipc::IPCResult
|
|
|
|
WebRenderBridgeParent::RecvForceComposite()
|
|
|
|
{
|
|
|
|
if (mDestroyed) {
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
ScheduleComposition();
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2017-05-28 14:48:36 +03:00
|
|
|
already_AddRefed<AsyncPanZoomController>
|
|
|
|
WebRenderBridgeParent::GetTargetAPZC(const FrameMetrics::ViewID& aScrollId)
|
|
|
|
{
|
|
|
|
RefPtr<AsyncPanZoomController> apzc;
|
|
|
|
if (CompositorBridgeParent* cbp = GetRootCompositorBridgeParent()) {
|
|
|
|
if (RefPtr<APZCTreeManager> apzctm = cbp->GetAPZCTreeManager()) {
|
2017-05-28 14:51:53 +03:00
|
|
|
apzc = apzctm->GetTargetAPZC(GetLayersId(), aScrollId);
|
2017-05-28 14:48:36 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return apzc.forget();
|
|
|
|
}
|
|
|
|
|
2017-05-28 14:51:51 +03:00
|
|
|
mozilla::ipc::IPCResult
|
|
|
|
WebRenderBridgeParent::RecvSetConfirmedTargetAPZC(const uint64_t& aBlockId,
|
|
|
|
nsTArray<ScrollableLayerGuid>&& aTargets)
|
|
|
|
{
|
2017-06-05 09:41:21 +03:00
|
|
|
if (mDestroyed) {
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
2017-05-28 14:51:53 +03:00
|
|
|
mCompositorBridge->SetConfirmedTargetAPZC(GetLayersId(), aBlockId, aTargets);
|
2017-05-28 14:51:51 +03:00
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2017-06-28 03:29:06 +03:00
|
|
|
mozilla::ipc::IPCResult
|
|
|
|
WebRenderBridgeParent::RecvSetTestSampleTime(const TimeStamp& aTime)
|
|
|
|
{
|
|
|
|
if (!mCompositorBridge->SetTestSampleTime(GetLayersId(), aTime)) {
|
|
|
|
return IPC_FAIL_NO_REASON(this);
|
|
|
|
}
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::ipc::IPCResult
|
|
|
|
WebRenderBridgeParent::RecvLeaveTestMode()
|
|
|
|
{
|
|
|
|
mCompositorBridge->LeaveTestMode(GetLayersId());
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::ipc::IPCResult
|
|
|
|
WebRenderBridgeParent::RecvGetAnimationOpacity(const uint64_t& aCompositorAnimationsId,
|
|
|
|
float* aOpacity,
|
|
|
|
bool* aHasAnimationOpacity)
|
|
|
|
{
|
|
|
|
if (mDestroyed) {
|
|
|
|
return IPC_FAIL_NO_REASON(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
MOZ_ASSERT(mAnimStorage);
|
|
|
|
AdvanceAnimations();
|
|
|
|
|
|
|
|
Maybe<float> opacity = mAnimStorage->GetAnimationOpacity(aCompositorAnimationsId);
|
|
|
|
if (opacity) {
|
|
|
|
*aOpacity = *opacity;
|
|
|
|
*aHasAnimationOpacity = true;
|
|
|
|
} else {
|
|
|
|
*aHasAnimationOpacity = false;
|
|
|
|
}
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::ipc::IPCResult
|
|
|
|
WebRenderBridgeParent::RecvGetAnimationTransform(const uint64_t& aCompositorAnimationsId,
|
|
|
|
MaybeTransform* aTransform)
|
|
|
|
{
|
|
|
|
if (mDestroyed) {
|
|
|
|
return IPC_FAIL_NO_REASON(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
MOZ_ASSERT(mAnimStorage);
|
|
|
|
AdvanceAnimations();
|
|
|
|
|
|
|
|
Maybe<Matrix4x4> transform = mAnimStorage->GetAnimationTransform(aCompositorAnimationsId);
|
|
|
|
if (transform) {
|
|
|
|
*aTransform = *transform;
|
|
|
|
} else {
|
|
|
|
*aTransform = mozilla::void_t();
|
|
|
|
}
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2017-05-28 14:48:36 +03:00
|
|
|
mozilla::ipc::IPCResult
|
|
|
|
WebRenderBridgeParent::RecvSetAsyncScrollOffset(const FrameMetrics::ViewID& aScrollId,
|
|
|
|
const float& aX,
|
|
|
|
const float& aY)
|
|
|
|
{
|
2017-06-05 09:41:21 +03:00
|
|
|
if (mDestroyed) {
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
2017-05-28 14:48:36 +03:00
|
|
|
RefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(aScrollId);
|
|
|
|
if (!apzc) {
|
|
|
|
return IPC_FAIL_NO_REASON(this);
|
|
|
|
}
|
|
|
|
apzc->SetTestAsyncScrollOffset(CSSPoint(aX, aY));
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::ipc::IPCResult
|
|
|
|
WebRenderBridgeParent::RecvSetAsyncZoom(const FrameMetrics::ViewID& aScrollId,
|
|
|
|
const float& aZoom)
|
|
|
|
{
|
2017-06-05 09:41:21 +03:00
|
|
|
if (mDestroyed) {
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
2017-05-28 14:48:36 +03:00
|
|
|
RefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(aScrollId);
|
|
|
|
if (!apzc) {
|
|
|
|
return IPC_FAIL_NO_REASON(this);
|
|
|
|
}
|
|
|
|
apzc->SetTestAsyncZoom(LayerToParentLayerScale(aZoom));
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::ipc::IPCResult
|
|
|
|
WebRenderBridgeParent::RecvFlushApzRepaints()
|
|
|
|
{
|
2017-06-05 09:41:21 +03:00
|
|
|
if (mDestroyed) {
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
2017-05-28 14:51:53 +03:00
|
|
|
mCompositorBridge->FlushApzRepaints(GetLayersId());
|
2017-05-28 14:48:36 +03:00
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2017-06-05 05:29:35 +03:00
|
|
|
mozilla::ipc::IPCResult
|
|
|
|
WebRenderBridgeParent::RecvGetAPZTestData(APZTestData* aOutData)
|
|
|
|
{
|
|
|
|
mCompositorBridge->GetAPZTestData(GetLayersId(), aOutData);
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2016-11-22 17:22:54 +03:00
|
|
|
void
|
|
|
|
WebRenderBridgeParent::ActorDestroy(ActorDestroyReason aWhy)
|
|
|
|
{
|
2016-11-28 04:21:33 +03:00
|
|
|
Destroy();
|
2016-11-22 17:22:54 +03:00
|
|
|
}
|
|
|
|
|
2017-06-28 03:29:05 +03:00
|
|
|
void
|
|
|
|
WebRenderBridgeParent::AdvanceAnimations()
|
|
|
|
{
|
|
|
|
TimeStamp animTime = mCompositorScheduler->GetLastComposeTime();
|
|
|
|
if (CompositorBridgeParent* cbp = GetRootCompositorBridgeParent()) {
|
|
|
|
animTime = cbp->GetTestingTimeStamp().valueOr(animTime);
|
|
|
|
}
|
2017-06-29 23:44:00 +03:00
|
|
|
|
|
|
|
AnimationHelper::SampleAnimations(mAnimStorage,
|
|
|
|
!mPreviousFrameTimeStamp.IsNull() ?
|
|
|
|
mPreviousFrameTimeStamp : animTime);
|
|
|
|
|
|
|
|
// Reset the previous time stamp if we don't already have any running
|
|
|
|
// animations to avoid using the time which is far behind for newly
|
|
|
|
// started animations.
|
|
|
|
mPreviousFrameTimeStamp =
|
|
|
|
mAnimStorage->AnimatedValueCount() ? animTime : TimeStamp();
|
2017-06-28 03:29:05 +03:00
|
|
|
}
|
|
|
|
|
2017-04-12 11:40:48 +03:00
|
|
|
void
|
2017-06-28 02:20:36 +03:00
|
|
|
WebRenderBridgeParent::SampleAnimations(nsTArray<wr::WrOpacityProperty>& aOpacityArray,
|
|
|
|
nsTArray<wr::WrTransformProperty>& aTransformArray)
|
2017-04-12 11:40:48 +03:00
|
|
|
{
|
2017-06-28 03:29:05 +03:00
|
|
|
AdvanceAnimations();
|
2017-04-12 11:40:48 +03:00
|
|
|
|
|
|
|
// return the animated data if has
|
2017-06-15 10:36:03 +03:00
|
|
|
if (mAnimStorage->AnimatedValueCount()) {
|
|
|
|
for(auto iter = mAnimStorage->ConstAnimatedValueTableIter();
|
2017-04-12 11:40:48 +03:00
|
|
|
!iter.Done(); iter.Next()) {
|
|
|
|
AnimatedValue * value = iter.UserData();
|
|
|
|
if (value->mType == AnimatedValue::TRANSFORM) {
|
|
|
|
aTransformArray.AppendElement(
|
|
|
|
wr::ToWrTransformProperty(iter.Key(), value->mTransform.mTransformInDevSpace));
|
|
|
|
} else if (value->mType == AnimatedValue::OPACITY) {
|
|
|
|
aOpacityArray.AppendElement(
|
|
|
|
wr::ToWrOpacityProperty(iter.Key(), value->mOpacity));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-22 05:56:38 +03:00
|
|
|
void
|
|
|
|
WebRenderBridgeParent::CompositeToTarget(gfx::DrawTarget* aTarget, const gfx::IntRect* aRect)
|
|
|
|
{
|
2017-06-07 05:33:19 +03:00
|
|
|
AutoProfilerTracing tracing("Paint", "CompositeToTraget");
|
2017-04-05 17:12:11 +03:00
|
|
|
if (mPaused) {
|
|
|
|
return;
|
|
|
|
}
|
2017-04-12 11:40:48 +03:00
|
|
|
|
2017-07-24 03:22:20 +03:00
|
|
|
const uint32_t maxPendingFrameCount = 1;
|
2017-05-19 03:21:38 +03:00
|
|
|
|
2017-06-02 02:07:59 +03:00
|
|
|
if (!mForceRendering &&
|
2017-07-24 03:22:20 +03:00
|
|
|
wr::RenderThread::Get()->GetPendingFrameCount(mApi->GetId()) >= maxPendingFrameCount) {
|
2017-05-19 03:21:38 +03:00
|
|
|
// Render thread is busy, try next time.
|
|
|
|
ScheduleComposition();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-05-23 17:50:42 +03:00
|
|
|
bool scheduleComposite = false;
|
2017-06-28 02:20:36 +03:00
|
|
|
nsTArray<wr::WrOpacityProperty> opacityArray;
|
|
|
|
nsTArray<wr::WrTransformProperty> transformArray;
|
2017-05-12 20:58:20 +03:00
|
|
|
|
2017-07-25 12:36:11 +03:00
|
|
|
mCompositableHolder->SetCompositionTime(TimeStamp::Now());
|
|
|
|
mCompositableHolder->ApplyAsyncImages(mApi);
|
2017-06-02 10:11:34 +03:00
|
|
|
|
2017-04-17 17:22:47 +03:00
|
|
|
if (gfxPrefs::WebRenderOMTAEnabled()) {
|
|
|
|
SampleAnimations(opacityArray, transformArray);
|
|
|
|
|
|
|
|
if (!transformArray.IsEmpty() || !opacityArray.IsEmpty()) {
|
2017-05-23 17:50:42 +03:00
|
|
|
scheduleComposite = true;
|
2017-04-17 17:22:47 +03:00
|
|
|
}
|
2017-04-12 11:40:48 +03:00
|
|
|
}
|
2017-04-17 17:22:47 +03:00
|
|
|
|
2017-05-23 17:50:42 +03:00
|
|
|
if (PushAPZStateToWR(transformArray)) {
|
|
|
|
scheduleComposite = true;
|
|
|
|
}
|
|
|
|
|
2017-07-24 03:22:20 +03:00
|
|
|
wr::RenderThread::Get()->IncPendingFrameCount(mApi->GetId());
|
|
|
|
|
2017-05-23 17:50:42 +03:00
|
|
|
if (!transformArray.IsEmpty() || !opacityArray.IsEmpty()) {
|
|
|
|
mApi->GenerateFrame(opacityArray, transformArray);
|
|
|
|
} else {
|
|
|
|
mApi->GenerateFrame();
|
|
|
|
}
|
2017-04-27 19:34:54 +03:00
|
|
|
|
2017-07-25 12:36:11 +03:00
|
|
|
if (!mCompositableHolder->GetCompositeUntilTime().IsNull()) {
|
2017-06-02 10:11:34 +03:00
|
|
|
scheduleComposite = true;
|
|
|
|
}
|
2017-05-23 17:50:42 +03:00
|
|
|
|
|
|
|
if (scheduleComposite) {
|
|
|
|
ScheduleComposition();
|
|
|
|
}
|
2016-11-22 05:56:38 +03:00
|
|
|
}
|
|
|
|
|
2017-01-06 21:10:15 +03:00
|
|
|
void
|
2017-02-24 06:22:59 +03:00
|
|
|
WebRenderBridgeParent::HoldPendingTransactionId(uint32_t aWrEpoch, uint64_t aTransactionId)
|
|
|
|
{
|
|
|
|
// The transaction ID might get reset to 1 if the page gets reloaded, see
|
|
|
|
// https://bugzilla.mozilla.org/show_bug.cgi?id=1145295#c41
|
|
|
|
// Otherwise, it should be continually increasing.
|
|
|
|
MOZ_ASSERT(aTransactionId == 1 || aTransactionId > LastPendingTransactionId());
|
|
|
|
// Handle TransactionIdAllocator(RefreshDriver) change.
|
|
|
|
if (aTransactionId == 1) {
|
|
|
|
FlushPendingTransactionIds();
|
|
|
|
}
|
|
|
|
mPendingTransactionIds.push(PendingTransactionId(wr::NewEpoch(aWrEpoch), aTransactionId));
|
|
|
|
}
|
|
|
|
|
|
|
|
uint64_t
|
|
|
|
WebRenderBridgeParent::LastPendingTransactionId()
|
2017-01-06 21:10:15 +03:00
|
|
|
{
|
2017-02-24 06:22:59 +03:00
|
|
|
uint64_t id = 0;
|
|
|
|
if (!mPendingTransactionIds.empty()) {
|
|
|
|
id = mPendingTransactionIds.back().mId;
|
|
|
|
}
|
|
|
|
return id;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint64_t
|
|
|
|
WebRenderBridgeParent::FlushPendingTransactionIds()
|
|
|
|
{
|
|
|
|
uint64_t id = 0;
|
|
|
|
while (!mPendingTransactionIds.empty()) {
|
|
|
|
id = mPendingTransactionIds.front().mId;
|
|
|
|
mPendingTransactionIds.pop();
|
|
|
|
}
|
|
|
|
return id;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint64_t
|
|
|
|
WebRenderBridgeParent::FlushTransactionIdsForEpoch(const wr::Epoch& aEpoch)
|
|
|
|
{
|
|
|
|
uint64_t id = 0;
|
|
|
|
while (!mPendingTransactionIds.empty()) {
|
2017-07-24 15:20:22 +03:00
|
|
|
int64_t diff =
|
|
|
|
static_cast<int64_t>(aEpoch.mHandle) - static_cast<int64_t>(mPendingTransactionIds.front().mEpoch.mHandle);
|
|
|
|
if (diff < 0) {
|
2017-02-24 06:22:59 +03:00
|
|
|
break;
|
|
|
|
}
|
2017-07-24 15:20:22 +03:00
|
|
|
id = mPendingTransactionIds.front().mId;
|
2017-02-24 06:22:59 +03:00
|
|
|
mPendingTransactionIds.pop();
|
2017-07-24 15:20:22 +03:00
|
|
|
if (diff == 0) {
|
|
|
|
break;
|
|
|
|
}
|
2017-02-24 06:22:59 +03:00
|
|
|
}
|
|
|
|
return id;
|
2017-01-06 21:10:15 +03:00
|
|
|
}
|
|
|
|
|
2017-05-28 14:51:53 +03:00
|
|
|
uint64_t
|
|
|
|
WebRenderBridgeParent::GetLayersId() const
|
|
|
|
{
|
|
|
|
return wr::AsUint64(mPipelineId);
|
|
|
|
}
|
|
|
|
|
2016-12-22 18:38:58 +03:00
|
|
|
void
|
|
|
|
WebRenderBridgeParent::DeleteOldImages()
|
|
|
|
{
|
2017-01-17 22:48:00 +03:00
|
|
|
for (wr::ImageKey key : mKeysToDelete) {
|
2017-02-10 18:16:47 +03:00
|
|
|
mApi->DeleteImage(key);
|
2016-12-22 18:38:58 +03:00
|
|
|
}
|
|
|
|
mKeysToDelete.clear();
|
|
|
|
}
|
|
|
|
|
2016-11-22 05:56:38 +03:00
|
|
|
void
|
|
|
|
WebRenderBridgeParent::ScheduleComposition()
|
|
|
|
{
|
2017-02-27 03:27:04 +03:00
|
|
|
if (mCompositorScheduler) {
|
|
|
|
mCompositorScheduler->ScheduleComposition();
|
|
|
|
}
|
2016-11-22 05:56:38 +03:00
|
|
|
}
|
|
|
|
|
2017-06-02 02:07:59 +03:00
|
|
|
void
|
|
|
|
WebRenderBridgeParent::FlushRendering(bool aIsSync)
|
|
|
|
{
|
|
|
|
if (mDestroyed) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!mCompositorScheduler->NeedsComposite()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
mForceRendering = true;
|
|
|
|
mCompositorScheduler->CancelCurrentCompositeTask();
|
|
|
|
mCompositorScheduler->ForceComposeToTarget(nullptr, nullptr);
|
|
|
|
if (aIsSync) {
|
|
|
|
mApi->WaitFlushed();
|
|
|
|
}
|
|
|
|
mForceRendering = false;
|
|
|
|
}
|
|
|
|
|
2017-04-05 17:12:11 +03:00
|
|
|
void
|
|
|
|
WebRenderBridgeParent::Pause()
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(mWidget);
|
|
|
|
#ifdef MOZ_WIDGET_ANDROID
|
|
|
|
if (!mWidget || mDestroyed) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
mApi->Pause();
|
|
|
|
#endif
|
|
|
|
mPaused = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
WebRenderBridgeParent::Resume()
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(mWidget);
|
|
|
|
#ifdef MOZ_WIDGET_ANDROID
|
|
|
|
if (!mWidget || mDestroyed) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!mApi->Resume()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
mPaused = false;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-11-22 17:22:54 +03:00
|
|
|
void
|
|
|
|
WebRenderBridgeParent::ClearResources()
|
|
|
|
{
|
2017-05-17 03:28:20 +03:00
|
|
|
if (!mApi) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-07-24 15:20:22 +03:00
|
|
|
uint32_t wrEpoch = GetNextWrEpoch();
|
|
|
|
mApi->ClearRootDisplayList(wr::NewEpoch(wrEpoch), mPipelineId);
|
2017-05-17 03:28:20 +03:00
|
|
|
// Schedule composition to clean up Pipeline
|
|
|
|
mCompositorScheduler->ScheduleComposition();
|
2017-06-30 04:06:11 +03:00
|
|
|
// XXX webrender does not hava a way to delete a group of resources/keys,
|
|
|
|
// then delete keys one by one.
|
2017-06-16 09:31:01 +03:00
|
|
|
for (std::unordered_set<uint64_t>::iterator iter = mFontKeys.begin(); iter != mFontKeys.end(); iter++) {
|
|
|
|
mApi->DeleteFont(wr::AsFontKey(*iter));
|
|
|
|
}
|
|
|
|
mFontKeys.clear();
|
|
|
|
for (std::unordered_set<uint64_t>::iterator iter = mActiveImageKeys.begin(); iter != mActiveImageKeys.end(); iter++) {
|
|
|
|
mKeysToDelete.push_back(wr::AsImageKey(*iter));
|
2017-03-06 04:42:17 +03:00
|
|
|
}
|
2017-06-16 09:31:01 +03:00
|
|
|
mActiveImageKeys.clear();
|
2017-05-17 03:28:20 +03:00
|
|
|
DeleteOldImages();
|
2017-04-27 19:34:54 +03:00
|
|
|
for (auto iter = mExternalImageIds.Iter(); !iter.Done(); iter.Next()) {
|
2017-05-18 13:50:03 +03:00
|
|
|
iter.Data()->ClearWrBridge();
|
2017-04-27 19:34:54 +03:00
|
|
|
}
|
2016-11-24 11:53:17 +03:00
|
|
|
mExternalImageIds.Clear();
|
2017-06-02 10:11:34 +03:00
|
|
|
for (auto iter = mAsyncCompositables.Iter(); !iter.Done(); iter.Next()) {
|
|
|
|
wr::PipelineId pipelineId = wr::AsPipelineId(iter.Key());
|
|
|
|
RefPtr<WebRenderImageHost> host = iter.Data();
|
|
|
|
MOZ_ASSERT(host->GetAsyncRef());
|
|
|
|
host->ClearWrBridge();
|
2017-07-25 12:36:11 +03:00
|
|
|
mCompositableHolder->RemoveAsyncImagePipeline(mApi, pipelineId);
|
2017-06-02 10:11:34 +03:00
|
|
|
}
|
|
|
|
mAsyncCompositables.Clear();
|
|
|
|
|
2017-07-25 12:36:11 +03:00
|
|
|
mCompositableHolder->RemovePipeline(mPipelineId, wr::NewEpoch(wrEpoch));
|
2016-11-24 11:53:17 +03:00
|
|
|
|
2017-06-15 10:36:03 +03:00
|
|
|
for (std::unordered_set<uint64_t>::iterator iter = mActiveAnimations.begin(); iter != mActiveAnimations.end(); iter++) {
|
|
|
|
mAnimStorage->ClearById(*iter);
|
|
|
|
}
|
|
|
|
mActiveAnimations.clear();
|
|
|
|
|
2017-05-17 03:28:20 +03:00
|
|
|
if (mWidget) {
|
2016-11-22 17:22:54 +03:00
|
|
|
mCompositorScheduler->Destroy();
|
|
|
|
}
|
2017-06-15 10:36:03 +03:00
|
|
|
mAnimStorage = nullptr;
|
2017-02-27 03:27:04 +03:00
|
|
|
mCompositorScheduler = nullptr;
|
2017-01-27 23:30:18 +03:00
|
|
|
mApi = nullptr;
|
2016-11-30 05:59:14 +03:00
|
|
|
mCompositorBridge = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
WebRenderBridgeParent::ShouldParentObserveEpoch()
|
|
|
|
{
|
|
|
|
if (mParentLayerObserverEpoch == mChildLayerObserverEpoch) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
mParentLayerObserverEpoch = mChildLayerObserverEpoch;
|
|
|
|
return true;
|
2016-11-22 17:22:54 +03:00
|
|
|
}
|
|
|
|
|
2016-11-30 13:57:26 +03:00
|
|
|
void
|
|
|
|
WebRenderBridgeParent::SendAsyncMessage(const InfallibleTArray<AsyncParentMessageData>& aMessage)
|
|
|
|
{
|
|
|
|
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
|
|
|
|
}
|
|
|
|
|
2016-12-07 13:02:04 +03:00
|
|
|
void
|
|
|
|
WebRenderBridgeParent::SendPendingAsyncMessages()
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(mCompositorBridge);
|
|
|
|
mCompositorBridge->SendPendingAsyncMessages();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
WebRenderBridgeParent::SetAboutToSendAsyncMessages()
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(mCompositorBridge);
|
|
|
|
mCompositorBridge->SetAboutToSendAsyncMessages();
|
|
|
|
}
|
|
|
|
|
2016-11-30 13:57:26 +03:00
|
|
|
void
|
|
|
|
WebRenderBridgeParent::NotifyNotUsed(PTextureParent* aTexture, uint64_t aTransactionId)
|
|
|
|
{
|
|
|
|
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
|
|
|
|
}
|
|
|
|
|
|
|
|
base::ProcessId
|
|
|
|
WebRenderBridgeParent::GetChildProcessId()
|
|
|
|
{
|
|
|
|
return OtherPid();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
WebRenderBridgeParent::IsSameProcess() const
|
|
|
|
{
|
|
|
|
return OtherPid() == base::GetCurrentProcId();
|
|
|
|
}
|
|
|
|
|
2017-01-18 21:47:27 +03:00
|
|
|
mozilla::ipc::IPCResult
|
|
|
|
WebRenderBridgeParent::RecvNewCompositable(const CompositableHandle& aHandle,
|
|
|
|
const TextureInfo& aInfo)
|
2016-11-30 13:57:26 +03:00
|
|
|
{
|
2017-06-05 09:41:21 +03:00
|
|
|
if (mDestroyed) {
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
2017-01-18 21:47:27 +03:00
|
|
|
if (!AddCompositable(aHandle, aInfo)) {
|
|
|
|
return IPC_FAIL_NO_REASON(this);
|
|
|
|
}
|
|
|
|
return IPC_OK();
|
2016-11-30 13:57:26 +03:00
|
|
|
}
|
|
|
|
|
2017-01-18 21:47:27 +03:00
|
|
|
mozilla::ipc::IPCResult
|
|
|
|
WebRenderBridgeParent::RecvReleaseCompositable(const CompositableHandle& aHandle)
|
2016-11-30 13:57:26 +03:00
|
|
|
{
|
2017-06-05 09:41:21 +03:00
|
|
|
if (mDestroyed) {
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
2017-01-18 21:47:27 +03:00
|
|
|
ReleaseCompositable(aHandle);
|
|
|
|
return IPC_OK();
|
2016-11-30 13:57:26 +03:00
|
|
|
}
|
|
|
|
|
2017-02-27 06:12:12 +03:00
|
|
|
mozilla::ipc::IPCResult
|
|
|
|
WebRenderBridgeParent::RecvInitReadLocks(ReadLockArray&& aReadLocks)
|
|
|
|
{
|
2017-06-05 09:41:21 +03:00
|
|
|
if (mDestroyed) {
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
2017-02-27 06:12:12 +03:00
|
|
|
if (!AddReadLocks(Move(aReadLocks))) {
|
|
|
|
return IPC_FAIL_NO_REASON(this);
|
|
|
|
}
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2016-11-29 05:06:25 +03:00
|
|
|
void
|
|
|
|
WebRenderBridgeParent::SetWebRenderProfilerEnabled(bool aEnabled)
|
|
|
|
{
|
|
|
|
if (mWidget) {
|
|
|
|
// Only set the flag to "root" WebRenderBridgeParent.
|
2017-02-10 18:16:47 +03:00
|
|
|
mApi->SetProfilerEnabled(aEnabled);
|
2016-11-29 05:06:25 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-01-18 22:50:00 +03:00
|
|
|
TextureFactoryIdentifier
|
|
|
|
WebRenderBridgeParent::GetTextureFactoryIdentifier()
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(mApi);
|
|
|
|
|
2017-01-22 07:24:52 +03:00
|
|
|
return TextureFactoryIdentifier(LayersBackend::LAYERS_WR,
|
2017-01-18 22:50:00 +03:00
|
|
|
XRE_GetProcessType(),
|
2017-02-23 11:46:56 +03:00
|
|
|
mApi->GetMaxTextureSize(),
|
|
|
|
mApi->GetUseANGLE());
|
2017-01-18 22:50:00 +03:00
|
|
|
}
|
|
|
|
|
2017-07-24 15:20:22 +03:00
|
|
|
uint32_t
|
|
|
|
WebRenderBridgeParent::GetNextWrEpoch()
|
|
|
|
{
|
|
|
|
MOZ_RELEASE_ASSERT(mWrEpoch != UINT32_MAX);
|
|
|
|
return ++mWrEpoch;
|
|
|
|
}
|
|
|
|
|
2016-11-16 16:54:51 +03:00
|
|
|
} // namespace layers
|
|
|
|
} // namespace mozilla
|