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-10 12:17:30 +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/. */
|
|
|
|
|
|
|
|
#include "WebRenderAPI.h"
|
2018-04-10 19:29:55 +03:00
|
|
|
|
2019-05-26 17:29:42 +03:00
|
|
|
#include "mozilla/StaticPrefs.h"
|
2017-05-29 18:40:49 +03:00
|
|
|
#include "LayersLogging.h"
|
2019-03-22 21:28:42 +03:00
|
|
|
#include "mozilla/ipc/ByteBuf.h"
|
2017-01-17 03:21:52 +03:00
|
|
|
#include "mozilla/webrender/RendererOGL.h"
|
2017-03-29 17:14:19 +03:00
|
|
|
#include "mozilla/gfx/gfxVars.h"
|
2017-01-10 12:17:30 +03:00
|
|
|
#include "mozilla/layers/CompositorThread.h"
|
2018-01-15 16:22:15 +03:00
|
|
|
#include "mozilla/webrender/RenderCompositor.h"
|
2017-01-10 12:17:30 +03:00
|
|
|
#include "mozilla/widget/CompositorWidget.h"
|
2017-01-11 15:51:27 +03:00
|
|
|
#include "mozilla/layers/SynchronousTask.h"
|
2018-11-26 01:57:04 +03:00
|
|
|
#include "TextDrawTarget.h"
|
2019-04-24 21:29:42 +03:00
|
|
|
#include "malloc_decls.h"
|
2017-01-10 12:17:30 +03:00
|
|
|
|
|
|
|
// clang-format off
|
2017-05-29 18:40:49 +03:00
|
|
|
#define WRDL_LOG(...)
|
2019-01-09 06:27:07 +03:00
|
|
|
//#define WRDL_LOG(...) printf_stderr("WRDL(%p): " __VA_ARGS__)
|
2019-01-10 16:35:18 +03:00
|
|
|
//#define WRDL_LOG(...) if (XRE_IsContentProcess()) printf_stderr("WRDL(%p): " __VA_ARGS__)
|
|
|
|
// clang-format on
|
2017-05-29 18:40:49 +03:00
|
|
|
|
2017-01-10 12:17:30 +03:00
|
|
|
namespace mozilla {
|
2017-01-17 03:22:09 +03:00
|
|
|
namespace wr {
|
2017-01-10 12:17:30 +03:00
|
|
|
|
2017-05-29 18:40:49 +03:00
|
|
|
using layers::Stringify;
|
|
|
|
|
2018-09-08 02:03:13 +03:00
|
|
|
MOZ_DEFINE_MALLOC_SIZE_OF(WebRenderMallocSizeOf)
|
2018-12-21 17:55:55 +03:00
|
|
|
MOZ_DEFINE_MALLOC_ENCLOSING_SIZE_OF(WebRenderMallocEnclosingSizeOf)
|
2018-09-08 02:03:13 +03:00
|
|
|
|
2017-01-10 12:17:30 +03:00
|
|
|
class NewRenderer : public RendererEvent {
|
|
|
|
public:
|
2018-05-28 18:29:41 +03:00
|
|
|
NewRenderer(wr::DocumentHandle** aDocHandle,
|
|
|
|
layers::CompositorBridgeParent* aBridge, int32_t* aMaxTextureSize,
|
2018-11-05 12:58:37 +03:00
|
|
|
bool* aUseANGLE, bool* aUseDComp, bool* aUseTripleBuffering,
|
2017-01-11 15:51:27 +03:00
|
|
|
RefPtr<widget::CompositorWidget>&& aWidget,
|
2017-01-17 03:22:09 +03:00
|
|
|
layers::SynchronousTask* aTask, LayoutDeviceIntSize aSize,
|
2017-08-07 13:15:25 +03:00
|
|
|
layers::SyncHandle* aHandle)
|
2017-08-09 15:46:24 +03:00
|
|
|
: mDocHandle(aDocHandle),
|
2017-01-25 00:06:17 +03:00
|
|
|
mMaxTextureSize(aMaxTextureSize),
|
2017-02-23 11:46:56 +03:00
|
|
|
mUseANGLE(aUseANGLE),
|
2018-07-20 16:58:40 +03:00
|
|
|
mUseDComp(aUseDComp),
|
2018-11-05 12:58:37 +03:00
|
|
|
mUseTripleBuffering(aUseTripleBuffering),
|
2017-01-25 00:06:17 +03:00
|
|
|
mBridge(aBridge),
|
2018-05-30 22:15:35 +03:00
|
|
|
mCompositorWidget(std::move(aWidget)),
|
2017-01-25 00:06:17 +03:00
|
|
|
mTask(aTask),
|
2017-03-07 02:46:30 +03:00
|
|
|
mSize(aSize),
|
2017-08-07 13:15:25 +03:00
|
|
|
mSyncHandle(aHandle) {
|
2017-01-10 12:17:30 +03:00
|
|
|
MOZ_COUNT_CTOR(NewRenderer);
|
|
|
|
}
|
|
|
|
|
|
|
|
~NewRenderer() { MOZ_COUNT_DTOR(NewRenderer); }
|
|
|
|
|
2019-04-11 15:36:51 +03:00
|
|
|
void Run(RenderThread& aRenderThread, WindowId aWindowId) override {
|
2017-01-17 03:22:09 +03:00
|
|
|
layers::AutoCompleteTask complete(mTask);
|
2017-01-11 15:51:27 +03:00
|
|
|
|
2018-05-30 22:15:35 +03:00
|
|
|
UniquePtr<RenderCompositor> compositor =
|
|
|
|
RenderCompositor::Create(std::move(mCompositorWidget));
|
2018-01-17 03:25:31 +03:00
|
|
|
if (!compositor) {
|
|
|
|
// RenderCompositor::Create puts a message into gfxCriticalNote if it is
|
|
|
|
// nullptr
|
|
|
|
return;
|
|
|
|
}
|
2017-01-11 15:51:27 +03:00
|
|
|
|
2018-01-15 16:22:15 +03:00
|
|
|
*mUseANGLE = compositor->UseANGLE();
|
2018-07-20 16:58:40 +03:00
|
|
|
*mUseDComp = compositor->UseDComp();
|
2018-11-05 12:58:37 +03:00
|
|
|
*mUseTripleBuffering = compositor->UseTripleBuffering();
|
2017-01-18 22:50:00 +03:00
|
|
|
|
2019-03-28 06:02:45 +03:00
|
|
|
bool isMainWindow = true; // TODO!
|
|
|
|
bool supportLowPriorityTransactions = isMainWindow;
|
|
|
|
bool supportPictureCaching = isMainWindow;
|
2017-07-19 10:28:58 +03:00
|
|
|
wr::Renderer* wrRenderer = nullptr;
|
2019-03-28 06:02:45 +03:00
|
|
|
if (!wr_window_new(
|
|
|
|
aWindowId, mSize.width, mSize.height,
|
|
|
|
supportLowPriorityTransactions,
|
2019-05-26 17:29:42 +03:00
|
|
|
StaticPrefs::WebRenderPictureCaching() && supportPictureCaching,
|
|
|
|
StaticPrefs::WebRenderStartDebugServer(), compositor->gl(),
|
2019-03-28 06:02:45 +03:00
|
|
|
aRenderThread.GetProgramCache()
|
|
|
|
? aRenderThread.GetProgramCache()->Raw()
|
|
|
|
: nullptr,
|
|
|
|
aRenderThread.GetShaders()
|
|
|
|
? aRenderThread.GetShaders()->RawShaders()
|
|
|
|
: nullptr,
|
|
|
|
aRenderThread.ThreadPool().Raw(), &WebRenderMallocSizeOf,
|
|
|
|
&WebRenderMallocEnclosingSizeOf, (uint32_t)wr::RenderRoot::Default,
|
|
|
|
mDocHandle, &wrRenderer, mMaxTextureSize)) {
|
2017-03-27 21:32:39 +03:00
|
|
|
// wr_window_new puts a message into gfxCriticalNote if it returns false
|
2017-02-14 21:34:15 +03:00
|
|
|
return;
|
|
|
|
}
|
2017-01-11 15:51:27 +03:00
|
|
|
MOZ_ASSERT(wrRenderer);
|
|
|
|
|
|
|
|
RefPtr<RenderThread> thread = &aRenderThread;
|
2018-05-30 22:15:35 +03:00
|
|
|
auto renderer =
|
|
|
|
MakeUnique<RendererOGL>(std::move(thread), std::move(compositor),
|
2017-01-11 15:51:27 +03:00
|
|
|
aWindowId, wrRenderer, mBridge);
|
2017-03-01 12:08:56 +03:00
|
|
|
if (wrRenderer && renderer) {
|
2017-06-28 02:20:36 +03:00
|
|
|
wr::WrExternalImageHandler handler = renderer->GetExternalImageHandler();
|
2017-03-01 12:08:56 +03:00
|
|
|
wr_renderer_set_external_image_handler(wrRenderer, &handler);
|
|
|
|
}
|
2017-01-11 15:51:27 +03:00
|
|
|
|
2017-08-07 13:15:25 +03:00
|
|
|
if (renderer) {
|
|
|
|
layers::SyncObjectHost* syncObj = renderer->GetSyncObject();
|
|
|
|
if (syncObj) {
|
|
|
|
*mSyncHandle = syncObj->GetSyncHandle();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-30 22:15:35 +03:00
|
|
|
aRenderThread.AddRenderer(aWindowId, std::move(renderer));
|
2017-01-10 12:17:30 +03:00
|
|
|
}
|
|
|
|
|
2017-01-25 00:20:54 +03:00
|
|
|
private:
|
2017-08-09 15:46:24 +03:00
|
|
|
wr::DocumentHandle** mDocHandle;
|
2018-11-16 20:13:26 +03:00
|
|
|
int32_t* mMaxTextureSize;
|
2017-02-23 11:46:56 +03:00
|
|
|
bool* mUseANGLE;
|
2018-07-20 16:58:40 +03:00
|
|
|
bool* mUseDComp;
|
2018-11-05 12:58:37 +03:00
|
|
|
bool* mUseTripleBuffering;
|
2018-05-28 18:29:41 +03:00
|
|
|
layers::CompositorBridgeParent* mBridge;
|
2017-01-10 12:17:30 +03:00
|
|
|
RefPtr<widget::CompositorWidget> mCompositorWidget;
|
2017-01-17 03:22:09 +03:00
|
|
|
layers::SynchronousTask* mTask;
|
2017-03-07 02:46:30 +03:00
|
|
|
LayoutDeviceIntSize mSize;
|
2017-08-07 13:15:25 +03:00
|
|
|
layers::SyncHandle* mSyncHandle;
|
2017-01-10 12:17:30 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
class RemoveRenderer : public RendererEvent {
|
|
|
|
public:
|
2017-01-17 03:22:09 +03:00
|
|
|
explicit RemoveRenderer(layers::SynchronousTask* aTask) : mTask(aTask) {
|
2017-01-11 15:51:27 +03:00
|
|
|
MOZ_COUNT_CTOR(RemoveRenderer);
|
|
|
|
}
|
2017-01-10 12:17:30 +03:00
|
|
|
|
2019-04-11 15:36:51 +03:00
|
|
|
virtual ~RemoveRenderer() { MOZ_COUNT_DTOR(RemoveRenderer); }
|
2017-01-10 12:17:30 +03:00
|
|
|
|
2019-04-11 15:36:51 +03:00
|
|
|
void Run(RenderThread& aRenderThread, WindowId aWindowId) override {
|
2017-01-10 12:17:30 +03:00
|
|
|
aRenderThread.RemoveRenderer(aWindowId);
|
2017-01-17 03:22:09 +03:00
|
|
|
layers::AutoCompleteTask complete(mTask);
|
2017-01-10 12:17:30 +03:00
|
|
|
}
|
2017-01-11 15:51:27 +03:00
|
|
|
|
2017-01-25 00:20:54 +03:00
|
|
|
private:
|
2017-01-17 03:22:09 +03:00
|
|
|
layers::SynchronousTask* mTask;
|
2017-01-10 12:17:30 +03:00
|
|
|
};
|
|
|
|
|
2018-05-11 16:09:19 +03:00
|
|
|
TransactionBuilder::TransactionBuilder(bool aUseSceneBuilderThread)
|
2018-07-10 15:49:21 +03:00
|
|
|
: mUseSceneBuilderThread(aUseSceneBuilderThread) {
|
2018-05-10 20:05:22 +03:00
|
|
|
mTxn = wr_transaction_new(mUseSceneBuilderThread);
|
2018-01-12 14:23:59 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
TransactionBuilder::~TransactionBuilder() { wr_transaction_delete(mTxn); }
|
|
|
|
|
2018-09-12 18:30:17 +03:00
|
|
|
void TransactionBuilder::SetLowPriority(bool aIsLowPriority) {
|
|
|
|
wr_transaction_set_low_priority(mTxn, aIsLowPriority);
|
|
|
|
}
|
|
|
|
|
2018-01-12 14:23:59 +03:00
|
|
|
void TransactionBuilder::UpdateEpoch(PipelineId aPipelineId, Epoch aEpoch) {
|
|
|
|
wr_transaction_update_epoch(mTxn, aPipelineId, aEpoch);
|
|
|
|
}
|
|
|
|
|
|
|
|
void TransactionBuilder::SetRootPipeline(PipelineId aPipelineId) {
|
|
|
|
wr_transaction_set_root_pipeline(mTxn, aPipelineId);
|
|
|
|
}
|
|
|
|
|
|
|
|
void TransactionBuilder::RemovePipeline(PipelineId aPipelineId) {
|
|
|
|
wr_transaction_remove_pipeline(mTxn, aPipelineId);
|
|
|
|
}
|
|
|
|
|
|
|
|
void TransactionBuilder::SetDisplayList(
|
2019-03-28 19:38:01 +03:00
|
|
|
gfx::Color aBgColor, Epoch aEpoch, const wr::LayoutSize& aViewportSize,
|
2018-01-12 14:23:59 +03:00
|
|
|
wr::WrPipelineId pipeline_id, const wr::LayoutSize& content_size,
|
|
|
|
wr::BuiltDisplayListDescriptor dl_descriptor, wr::Vec<uint8_t>& dl_data) {
|
|
|
|
wr_transaction_set_display_list(mTxn, aEpoch, ToColorF(aBgColor),
|
2019-03-30 09:41:48 +03:00
|
|
|
aViewportSize, pipeline_id, content_size,
|
|
|
|
dl_descriptor, &dl_data.inner);
|
2018-01-12 14:23:59 +03:00
|
|
|
}
|
|
|
|
|
2018-01-12 14:24:07 +03:00
|
|
|
void TransactionBuilder::ClearDisplayList(Epoch aEpoch,
|
|
|
|
wr::WrPipelineId aPipelineId) {
|
|
|
|
wr_transaction_clear_display_list(mTxn, aEpoch, aPipelineId);
|
|
|
|
}
|
|
|
|
|
2018-01-12 14:23:59 +03:00
|
|
|
void TransactionBuilder::GenerateFrame() {
|
|
|
|
wr_transaction_generate_frame(mTxn);
|
|
|
|
}
|
|
|
|
|
2018-10-10 06:20:23 +03:00
|
|
|
void TransactionBuilder::InvalidateRenderedFrame() {
|
|
|
|
wr_transaction_invalidate_rendered_frame(mTxn);
|
|
|
|
}
|
|
|
|
|
2018-01-12 14:23:59 +03:00
|
|
|
void TransactionBuilder::UpdateDynamicProperties(
|
|
|
|
const nsTArray<wr::WrOpacityProperty>& aOpacityArray,
|
|
|
|
const nsTArray<wr::WrTransformProperty>& aTransformArray) {
|
2018-04-11 22:28:00 +03:00
|
|
|
wr_transaction_update_dynamic_properties(
|
|
|
|
mTxn, aOpacityArray.IsEmpty() ? nullptr : aOpacityArray.Elements(),
|
|
|
|
aOpacityArray.Length(),
|
|
|
|
aTransformArray.IsEmpty() ? nullptr : aTransformArray.Elements(),
|
|
|
|
aTransformArray.Length());
|
|
|
|
}
|
|
|
|
|
2018-01-12 14:23:59 +03:00
|
|
|
bool TransactionBuilder::IsEmpty() const {
|
|
|
|
return wr_transaction_is_empty(mTxn);
|
|
|
|
}
|
|
|
|
|
2018-11-26 10:08:49 +03:00
|
|
|
bool TransactionBuilder::IsResourceUpdatesEmpty() const {
|
|
|
|
return wr_transaction_resource_updates_is_empty(mTxn);
|
|
|
|
}
|
|
|
|
|
2019-03-12 15:48:34 +03:00
|
|
|
bool TransactionBuilder::IsRenderedFrameInvalidated() const {
|
|
|
|
return wr_transaction_is_rendered_frame_invalidated(mTxn);
|
|
|
|
}
|
|
|
|
|
2019-03-01 20:16:59 +03:00
|
|
|
void TransactionBuilder::SetDocumentView(
|
2019-04-25 16:02:47 +03:00
|
|
|
const LayoutDeviceIntRect& aDocumentRect) {
|
|
|
|
wr::DeviceIntRect wrDocRect;
|
2018-01-29 16:33:35 +03:00
|
|
|
wrDocRect.origin.x = aDocumentRect.x;
|
2019-04-25 16:02:47 +03:00
|
|
|
wrDocRect.origin.y = aDocumentRect.y;
|
2018-01-29 16:33:35 +03:00
|
|
|
wrDocRect.size.width = aDocumentRect.width;
|
|
|
|
wrDocRect.size.height = aDocumentRect.height;
|
2019-03-01 20:16:59 +03:00
|
|
|
wr_transaction_set_document_view(mTxn, &wrDocRect);
|
2018-01-12 14:23:59 +03:00
|
|
|
}
|
|
|
|
|
2018-01-17 19:19:39 +03:00
|
|
|
void TransactionBuilder::UpdateScrollPosition(
|
|
|
|
const wr::WrPipelineId& aPipelineId,
|
2018-11-01 23:15:46 +03:00
|
|
|
const layers::ScrollableLayerGuid::ViewID& aScrollId,
|
2018-01-17 19:19:39 +03:00
|
|
|
const wr::LayoutPoint& aScrollPosition) {
|
|
|
|
wr_transaction_scroll_layer(mTxn, aPipelineId, aScrollId, aScrollPosition);
|
|
|
|
}
|
|
|
|
|
2018-04-17 00:39:26 +03:00
|
|
|
TransactionWrapper::TransactionWrapper(Transaction* aTxn) : mTxn(aTxn) {}
|
|
|
|
|
|
|
|
void TransactionWrapper::AppendTransformProperties(
|
|
|
|
const nsTArray<wr::WrTransformProperty>& aTransformArray) {
|
|
|
|
wr_transaction_append_transform_properties(
|
|
|
|
mTxn, aTransformArray.IsEmpty() ? nullptr : aTransformArray.Elements(),
|
|
|
|
aTransformArray.Length());
|
|
|
|
}
|
|
|
|
|
|
|
|
void TransactionWrapper::UpdateScrollPosition(
|
|
|
|
const wr::WrPipelineId& aPipelineId,
|
2018-11-01 23:15:46 +03:00
|
|
|
const layers::ScrollableLayerGuid::ViewID& aScrollId,
|
2018-04-17 00:39:26 +03:00
|
|
|
const wr::LayoutPoint& aScrollPosition) {
|
|
|
|
wr_transaction_scroll_layer(mTxn, aPipelineId, aScrollId, aScrollPosition);
|
|
|
|
}
|
2018-01-12 14:23:59 +03:00
|
|
|
|
2018-10-19 17:24:14 +03:00
|
|
|
void TransactionWrapper::UpdatePinchZoom(float aZoom) {
|
|
|
|
wr_transaction_pinch_zoom(mTxn, aZoom);
|
|
|
|
}
|
|
|
|
|
2019-05-22 23:13:34 +03:00
|
|
|
void TransactionWrapper::UpdateIsTransformPinchZooming(uint64_t aAnimationId,
|
|
|
|
bool aIsZooming) {
|
|
|
|
wr_transaction_set_is_transform_pinch_zooming(mTxn, aAnimationId, aIsZooming);
|
|
|
|
}
|
|
|
|
|
2019-02-26 01:07:19 +03:00
|
|
|
/*static*/
|
|
|
|
already_AddRefed<WebRenderAPI> WebRenderAPI::Create(
|
2018-04-10 19:29:55 +03:00
|
|
|
layers::CompositorBridgeParent* aBridge,
|
2017-03-07 02:46:30 +03:00
|
|
|
RefPtr<widget::CompositorWidget>&& aWidget, const wr::WrWindowId& aWindowId,
|
|
|
|
LayoutDeviceIntSize aSize) {
|
2017-01-10 12:17:30 +03:00
|
|
|
MOZ_ASSERT(aBridge);
|
|
|
|
MOZ_ASSERT(aWidget);
|
2018-03-12 23:38:10 +03:00
|
|
|
static_assert(
|
|
|
|
sizeof(size_t) == sizeof(uintptr_t),
|
|
|
|
"The FFI bindings assume size_t is the same size as uintptr_t!");
|
2017-01-10 12:17:30 +03:00
|
|
|
|
2017-08-09 15:46:24 +03:00
|
|
|
wr::DocumentHandle* docHandle = nullptr;
|
2018-11-16 20:13:26 +03:00
|
|
|
int32_t maxTextureSize = 0;
|
2017-02-23 11:46:56 +03:00
|
|
|
bool useANGLE = false;
|
2018-07-20 16:58:40 +03:00
|
|
|
bool useDComp = false;
|
2018-11-05 12:58:37 +03:00
|
|
|
bool useTripleBuffering = false;
|
2017-08-07 13:15:25 +03:00
|
|
|
layers::SyncHandle syncHandle = 0;
|
2017-01-10 12:17:30 +03:00
|
|
|
|
2017-08-09 15:46:24 +03:00
|
|
|
// Dispatch a synchronous task because the DocumentHandle object needs to be
|
2017-01-11 15:51:27 +03:00
|
|
|
// created on the render thread. If need be we could delay waiting on this
|
2017-08-09 15:46:24 +03:00
|
|
|
// task until the next time we need to access the DocumentHandle object.
|
2017-01-17 03:22:09 +03:00
|
|
|
layers::SynchronousTask task("Create Renderer");
|
2018-11-05 12:58:37 +03:00
|
|
|
auto event = MakeUnique<NewRenderer>(
|
|
|
|
&docHandle, aBridge, &maxTextureSize, &useANGLE, &useDComp,
|
2018-05-30 22:15:35 +03:00
|
|
|
&useTripleBuffering, std::move(aWidget), &task, aSize, &syncHandle);
|
|
|
|
RenderThread::Get()->RunEvent(aWindowId, std::move(event));
|
2017-01-10 12:17:30 +03:00
|
|
|
|
2017-01-11 15:51:27 +03:00
|
|
|
task.Wait();
|
2017-01-10 12:17:30 +03:00
|
|
|
|
2017-08-09 15:46:24 +03:00
|
|
|
if (!docHandle) {
|
2017-01-11 15:51:27 +03:00
|
|
|
return nullptr;
|
|
|
|
}
|
2017-01-10 12:17:30 +03:00
|
|
|
|
2018-11-05 12:58:37 +03:00
|
|
|
return RefPtr<WebRenderAPI>(
|
|
|
|
new WebRenderAPI(docHandle, aWindowId, maxTextureSize, useANGLE,
|
2019-03-22 21:28:42 +03:00
|
|
|
useDComp, useTripleBuffering, syncHandle,
|
|
|
|
wr::RenderRoot::Default))
|
2018-11-05 12:58:37 +03:00
|
|
|
.forget();
|
2017-01-10 12:17:30 +03:00
|
|
|
}
|
|
|
|
|
2017-08-09 15:46:25 +03:00
|
|
|
already_AddRefed<WebRenderAPI> WebRenderAPI::Clone() {
|
|
|
|
wr::DocumentHandle* docHandle = nullptr;
|
|
|
|
wr_api_clone(mDocHandle, &docHandle);
|
|
|
|
|
2018-11-05 12:58:37 +03:00
|
|
|
RefPtr<WebRenderAPI> renderApi =
|
|
|
|
new WebRenderAPI(docHandle, mId, mMaxTextureSize, mUseANGLE, mUseDComp,
|
2019-03-22 21:28:42 +03:00
|
|
|
mUseTripleBuffering, mSyncHandle, mRenderRoot);
|
2017-08-09 15:46:25 +03:00
|
|
|
renderApi->mRootApi = this; // Hold root api
|
2018-01-29 16:33:35 +03:00
|
|
|
renderApi->mRootDocumentApi = this;
|
2017-08-09 15:46:25 +03:00
|
|
|
return renderApi.forget();
|
|
|
|
}
|
|
|
|
|
2018-01-29 16:33:35 +03:00
|
|
|
already_AddRefed<WebRenderAPI> WebRenderAPI::CreateDocument(
|
2019-03-22 21:28:42 +03:00
|
|
|
LayoutDeviceIntSize aSize, int8_t aLayerIndex, wr::RenderRoot aRenderRoot) {
|
2019-04-25 16:02:47 +03:00
|
|
|
wr::DeviceIntSize wrSize;
|
2018-01-29 16:33:35 +03:00
|
|
|
wrSize.width = aSize.width;
|
|
|
|
wrSize.height = aSize.height;
|
|
|
|
wr::DocumentHandle* newDoc;
|
|
|
|
|
2019-03-22 21:28:42 +03:00
|
|
|
wr_api_create_document(mDocHandle, &newDoc, wrSize, aLayerIndex,
|
|
|
|
(uint32_t)aRenderRoot);
|
2018-01-29 16:33:35 +03:00
|
|
|
|
2019-03-22 21:28:42 +03:00
|
|
|
RefPtr<WebRenderAPI> api(
|
|
|
|
new WebRenderAPI(newDoc, mId, mMaxTextureSize, mUseANGLE, mUseDComp,
|
|
|
|
mUseTripleBuffering, mSyncHandle, aRenderRoot));
|
2018-01-29 16:33:35 +03:00
|
|
|
api->mRootApi = this;
|
|
|
|
return api.forget();
|
|
|
|
}
|
|
|
|
|
2017-02-22 21:19:57 +03:00
|
|
|
wr::WrIdNamespace WebRenderAPI::GetNamespace() {
|
2017-08-09 15:46:24 +03:00
|
|
|
return wr_api_get_namespace(mDocHandle);
|
2017-02-22 21:19:57 +03:00
|
|
|
}
|
|
|
|
|
2019-03-22 21:28:42 +03:00
|
|
|
WebRenderAPI::WebRenderAPI(wr::DocumentHandle* aHandle, wr::WindowId aId,
|
|
|
|
uint32_t aMaxTextureSize, bool aUseANGLE,
|
|
|
|
bool aUseDComp, bool aUseTripleBuffering,
|
|
|
|
layers::SyncHandle aSyncHandle,
|
|
|
|
wr::RenderRoot aRenderRoot)
|
|
|
|
: mDocHandle(aHandle),
|
|
|
|
mId(aId),
|
|
|
|
mMaxTextureSize(aMaxTextureSize),
|
|
|
|
mUseANGLE(aUseANGLE),
|
|
|
|
mUseDComp(aUseDComp),
|
|
|
|
mUseTripleBuffering(aUseTripleBuffering),
|
|
|
|
mSyncHandle(aSyncHandle),
|
|
|
|
mDebugFlags({0}),
|
|
|
|
mRenderRoot(aRenderRoot) {}
|
|
|
|
|
2017-01-10 12:17:30 +03:00
|
|
|
WebRenderAPI::~WebRenderAPI() {
|
2018-01-29 16:33:35 +03:00
|
|
|
if (!mRootDocumentApi) {
|
|
|
|
wr_api_delete_document(mDocHandle);
|
|
|
|
}
|
2017-11-24 12:34:50 +03:00
|
|
|
|
2018-01-29 16:33:35 +03:00
|
|
|
if (!mRootApi) {
|
2017-11-24 12:34:50 +03:00
|
|
|
RenderThread::Get()->SetDestroyed(GetId());
|
|
|
|
|
2017-08-09 15:46:25 +03:00
|
|
|
layers::SynchronousTask task("Destroy WebRenderAPI");
|
|
|
|
auto event = MakeUnique<RemoveRenderer>(&task);
|
2018-05-30 22:15:35 +03:00
|
|
|
RunOnRenderThread(std::move(event));
|
2017-08-09 15:46:25 +03:00
|
|
|
task.Wait();
|
2018-01-29 16:33:35 +03:00
|
|
|
|
|
|
|
wr_api_shut_down(mDocHandle);
|
2017-08-09 15:46:25 +03:00
|
|
|
}
|
2017-01-10 12:17:30 +03:00
|
|
|
|
2017-08-09 15:46:24 +03:00
|
|
|
wr_api_delete(mDocHandle);
|
2017-01-10 12:17:30 +03:00
|
|
|
}
|
|
|
|
|
2018-11-15 02:10:57 +03:00
|
|
|
void WebRenderAPI::UpdateDebugFlags(uint32_t aFlags) {
|
2019-03-07 02:01:11 +03:00
|
|
|
if (mDebugFlags.bits != aFlags) {
|
|
|
|
mDebugFlags.bits = aFlags;
|
2018-11-15 02:10:57 +03:00
|
|
|
wr_api_set_debug_flags(mDocHandle, mDebugFlags);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-01-12 14:23:59 +03:00
|
|
|
void WebRenderAPI::SendTransaction(TransactionBuilder& aTxn) {
|
2018-11-15 02:10:57 +03:00
|
|
|
UpdateDebugFlags(gfx::gfxVars::WebRenderDebugFlags());
|
2018-05-10 20:05:22 +03:00
|
|
|
wr_api_send_transaction(mDocHandle, aTxn.Raw(), aTxn.UseSceneBuilderThread());
|
2018-01-12 14:23:59 +03:00
|
|
|
}
|
|
|
|
|
2019-04-16 01:34:13 +03:00
|
|
|
/* static */
|
|
|
|
void WebRenderAPI::SendTransactions(
|
|
|
|
const RenderRootArray<RefPtr<WebRenderAPI>>& aApis,
|
|
|
|
RenderRootArray<TransactionBuilder*>& aTxns) {
|
|
|
|
if (!aApis[RenderRoot::Default]) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
aApis[RenderRoot::Default]->UpdateDebugFlags(
|
|
|
|
gfx::gfxVars::WebRenderDebugFlags());
|
|
|
|
AutoTArray<DocumentHandle*, kRenderRootCount> documentHandles;
|
|
|
|
AutoTArray<Transaction*, kRenderRootCount> txns;
|
|
|
|
Maybe<bool> useSceneBuilderThread;
|
|
|
|
for (auto& api : aApis) {
|
|
|
|
if (!api) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
auto& txn = aTxns[api->GetRenderRoot()];
|
|
|
|
if (txn) {
|
|
|
|
documentHandles.AppendElement(api->mDocHandle);
|
|
|
|
txns.AppendElement(txn->Raw());
|
|
|
|
if (useSceneBuilderThread.isSome()) {
|
|
|
|
MOZ_ASSERT(txn->UseSceneBuilderThread() == *useSceneBuilderThread);
|
|
|
|
} else {
|
|
|
|
useSceneBuilderThread.emplace(txn->UseSceneBuilderThread());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!txns.IsEmpty()) {
|
|
|
|
wr_api_send_transactions(documentHandles.Elements(), txns.Elements(),
|
|
|
|
txns.Length(), *useSceneBuilderThread);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-15 19:39:44 +03:00
|
|
|
bool WebRenderAPI::HitTest(const wr::WorldPoint& aPoint,
|
|
|
|
wr::WrPipelineId& aOutPipelineId,
|
2018-11-01 23:15:46 +03:00
|
|
|
layers::ScrollableLayerGuid::ViewID& aOutScrollId,
|
2017-11-15 19:39:44 +03:00
|
|
|
gfx::CompositorHitTestInfo& aOutHitInfo) {
|
2018-09-25 21:47:55 +03:00
|
|
|
static_assert(DoesCompositorHitTestInfoFitIntoBits<16>(),
|
|
|
|
"CompositorHitTestFlags MAX value has to be less than number "
|
|
|
|
"of bits in uint16_t");
|
|
|
|
|
|
|
|
uint16_t serialized = static_cast<uint16_t>(aOutHitInfo.serialize());
|
|
|
|
const bool result = wr_api_hit_test(mDocHandle, aPoint, &aOutPipelineId,
|
|
|
|
&aOutScrollId, &serialized);
|
|
|
|
|
|
|
|
if (result) {
|
|
|
|
aOutHitInfo.deserialize(serialized);
|
|
|
|
}
|
|
|
|
return result;
|
2017-11-15 19:39:44 +03:00
|
|
|
}
|
|
|
|
|
2018-06-26 00:37:35 +03:00
|
|
|
void WebRenderAPI::Readback(const TimeStamp& aStartTime, gfx::IntSize size,
|
2019-04-30 20:49:30 +03:00
|
|
|
const gfx::SurfaceFormat& aFormat,
|
2018-10-17 01:54:01 +03:00
|
|
|
const Range<uint8_t>& buffer) {
|
2017-01-25 07:29:34 +03:00
|
|
|
class Readback : public RendererEvent {
|
|
|
|
public:
|
2018-11-04 23:35:36 +03:00
|
|
|
explicit Readback(layers::SynchronousTask* aTask, TimeStamp aStartTime,
|
2019-04-30 20:49:30 +03:00
|
|
|
gfx::IntSize aSize, const gfx::SurfaceFormat& aFormat,
|
|
|
|
const Range<uint8_t>& aBuffer)
|
2019-05-25 20:46:15 +03:00
|
|
|
: mTask(aTask),
|
|
|
|
mStartTime(aStartTime),
|
|
|
|
mSize(aSize),
|
|
|
|
mFormat(aFormat),
|
2019-04-30 20:49:30 +03:00
|
|
|
mBuffer(aBuffer) {
|
2018-10-17 01:54:01 +03:00
|
|
|
MOZ_COUNT_CTOR(Readback);
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
2017-03-07 13:37:28 +03:00
|
|
|
|
2019-04-11 15:36:51 +03:00
|
|
|
virtual ~Readback() { MOZ_COUNT_DTOR(Readback); }
|
2018-11-15 02:10:57 +03:00
|
|
|
|
2019-04-11 15:36:51 +03:00
|
|
|
void Run(RenderThread& aRenderThread, WindowId aWindowId) override {
|
2018-12-08 02:28:41 +03:00
|
|
|
aRenderThread.UpdateAndRender(aWindowId, VsyncId(), mStartTime,
|
|
|
|
/* aRender */ true, Some(mSize),
|
2019-04-30 20:49:30 +03:00
|
|
|
wr::SurfaceFormatToImageFormat(mFormat),
|
2018-12-08 02:28:41 +03:00
|
|
|
Some(mBuffer), false);
|
2017-04-05 17:12:11 +03:00
|
|
|
layers::AutoCompleteTask complete(mTask);
|
|
|
|
}
|
|
|
|
|
2017-01-25 07:29:34 +03:00
|
|
|
layers::SynchronousTask* mTask;
|
2018-06-26 00:37:35 +03:00
|
|
|
TimeStamp mStartTime;
|
2017-01-25 07:29:34 +03:00
|
|
|
gfx::IntSize mSize;
|
2019-04-30 20:49:30 +03:00
|
|
|
gfx::SurfaceFormat mFormat;
|
2018-10-17 01:54:01 +03:00
|
|
|
const Range<uint8_t>& mBuffer;
|
2018-11-30 13:46:48 +03:00
|
|
|
};
|
|
|
|
|
2018-11-15 02:10:57 +03:00
|
|
|
// Disable debug flags during readback. See bug 1436020.
|
|
|
|
UpdateDebugFlags(0);
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2017-01-25 07:29:34 +03:00
|
|
|
layers::SynchronousTask task("Readback");
|
2019-04-30 20:49:30 +03:00
|
|
|
auto event = MakeUnique<Readback>(&task, aStartTime, size, aFormat, buffer);
|
2017-02-16 06:32:34 +03:00
|
|
|
// This event will be passed from wr_backend thread to renderer thread. That
|
|
|
|
// implies that all frame data have been processed when the renderer runs this
|
2017-03-07 13:37:28 +03:00
|
|
|
// read-back event. Then, we could make sure this read-back event gets the
|
|
|
|
// latest result.
|
2018-05-30 22:15:35 +03:00
|
|
|
RunOnRenderThread(std::move(event));
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2017-04-05 17:12:11 +03:00
|
|
|
task.Wait();
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2018-11-15 02:10:57 +03:00
|
|
|
UpdateDebugFlags(gfx::gfxVars::WebRenderDebugFlags());
|
2017-04-05 17:12:11 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void WebRenderAPI::ClearAllCaches() { wr_api_clear_all_caches(mDocHandle); }
|
|
|
|
|
|
|
|
void WebRenderAPI::Pause() {
|
|
|
|
class PauseEvent : public RendererEvent {
|
2018-11-30 13:46:48 +03:00
|
|
|
public:
|
2017-04-05 17:12:11 +03:00
|
|
|
explicit PauseEvent(layers::SynchronousTask* aTask) : mTask(aTask) {
|
|
|
|
MOZ_COUNT_CTOR(PauseEvent);
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
|
|
|
|
2019-04-11 15:36:51 +03:00
|
|
|
virtual ~PauseEvent() { MOZ_COUNT_DTOR(PauseEvent); }
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2019-04-11 15:36:51 +03:00
|
|
|
void Run(RenderThread& aRenderThread, WindowId aWindowId) override {
|
2017-04-05 17:12:11 +03:00
|
|
|
aRenderThread.Pause(aWindowId);
|
2017-01-25 07:29:34 +03:00
|
|
|
layers::AutoCompleteTask complete(mTask);
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
|
|
|
|
2017-01-25 07:29:34 +03:00
|
|
|
layers::SynchronousTask* mTask;
|
2018-11-30 13:46:48 +03:00
|
|
|
};
|
|
|
|
|
2017-04-05 17:12:11 +03:00
|
|
|
layers::SynchronousTask task("Pause");
|
|
|
|
auto event = MakeUnique<PauseEvent>(&task);
|
2017-02-16 06:32:34 +03:00
|
|
|
// This event will be passed from wr_backend thread to renderer thread. That
|
|
|
|
// implies that all frame data have been processed when the renderer runs this
|
2017-03-07 13:37:28 +03:00
|
|
|
// event.
|
2018-05-30 22:15:35 +03:00
|
|
|
RunOnRenderThread(std::move(event));
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2017-04-05 17:12:11 +03:00
|
|
|
task.Wait();
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
|
|
|
|
2017-04-05 17:12:11 +03:00
|
|
|
bool WebRenderAPI::Resume() {
|
|
|
|
class ResumeEvent : public RendererEvent {
|
2018-11-30 13:46:48 +03:00
|
|
|
public:
|
2017-04-05 17:12:11 +03:00
|
|
|
explicit ResumeEvent(layers::SynchronousTask* aTask, bool* aResult)
|
|
|
|
: mTask(aTask), mResult(aResult) {
|
|
|
|
MOZ_COUNT_CTOR(ResumeEvent);
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
|
|
|
|
2019-04-11 15:36:51 +03:00
|
|
|
virtual ~ResumeEvent() { MOZ_COUNT_DTOR(ResumeEvent); }
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2019-04-11 15:36:51 +03:00
|
|
|
void Run(RenderThread& aRenderThread, WindowId aWindowId) override {
|
2017-04-05 17:12:11 +03:00
|
|
|
*mResult = aRenderThread.Resume(aWindowId);
|
2017-01-25 07:29:34 +03:00
|
|
|
layers::AutoCompleteTask complete(mTask);
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
|
|
|
|
2017-01-25 07:29:34 +03:00
|
|
|
layers::SynchronousTask* mTask;
|
2017-04-05 17:12:11 +03:00
|
|
|
bool* mResult;
|
2018-11-30 13:46:48 +03:00
|
|
|
};
|
|
|
|
|
2017-04-05 17:12:11 +03:00
|
|
|
bool result = false;
|
|
|
|
layers::SynchronousTask task("Resume");
|
|
|
|
auto event = MakeUnique<ResumeEvent>(&task, &result);
|
2017-02-16 06:32:34 +03:00
|
|
|
// This event will be passed from wr_backend thread to renderer thread. That
|
|
|
|
// implies that all frame data have been processed when the renderer runs this
|
2017-03-07 13:37:28 +03:00
|
|
|
// event.
|
2018-05-30 22:15:35 +03:00
|
|
|
RunOnRenderThread(std::move(event));
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2017-08-09 15:46:25 +03:00
|
|
|
task.Wait();
|
2017-04-05 17:12:11 +03:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2018-08-20 16:23:54 +03:00
|
|
|
void WebRenderAPI::NotifyMemoryPressure() {
|
|
|
|
wr_api_notify_memory_pressure(mDocHandle);
|
|
|
|
}
|
|
|
|
|
2018-09-08 02:03:13 +03:00
|
|
|
void WebRenderAPI::AccumulateMemoryReport(MemoryReport* aReport) {
|
|
|
|
wr_api_accumulate_memory_report(mDocHandle, aReport);
|
|
|
|
}
|
|
|
|
|
2018-04-10 19:29:55 +03:00
|
|
|
void WebRenderAPI::WakeSceneBuilder() { wr_api_wake_scene_builder(mDocHandle); }
|
|
|
|
|
2018-04-27 17:46:21 +03:00
|
|
|
void WebRenderAPI::FlushSceneBuilder() {
|
|
|
|
wr_api_flush_scene_builder(mDocHandle);
|
|
|
|
}
|
|
|
|
|
2017-03-07 13:37:28 +03:00
|
|
|
void WebRenderAPI::WaitFlushed() {
|
|
|
|
class WaitFlushedEvent : public RendererEvent {
|
|
|
|
public:
|
|
|
|
explicit WaitFlushedEvent(layers::SynchronousTask* aTask) : mTask(aTask) {
|
|
|
|
MOZ_COUNT_CTOR(WaitFlushedEvent);
|
|
|
|
}
|
|
|
|
|
2019-04-11 15:36:51 +03:00
|
|
|
virtual ~WaitFlushedEvent() { MOZ_COUNT_DTOR(WaitFlushedEvent); }
|
2017-03-07 13:37:28 +03:00
|
|
|
|
2019-04-11 15:36:51 +03:00
|
|
|
void Run(RenderThread& aRenderThread, WindowId aWindowId) override {
|
2017-03-07 13:37:28 +03:00
|
|
|
layers::AutoCompleteTask complete(mTask);
|
|
|
|
}
|
|
|
|
|
|
|
|
layers::SynchronousTask* mTask;
|
|
|
|
};
|
|
|
|
|
|
|
|
layers::SynchronousTask task("WaitFlushed");
|
|
|
|
auto event = MakeUnique<WaitFlushedEvent>(&task);
|
|
|
|
// This event will be passed from wr_backend thread to renderer thread. That
|
2017-04-05 17:12:11 +03:00
|
|
|
// implies that all frame data have been processed when the renderer runs this
|
|
|
|
// event.
|
2018-05-30 22:15:35 +03:00
|
|
|
RunOnRenderThread(std::move(event));
|
2017-01-25 07:29:34 +03:00
|
|
|
|
|
|
|
task.Wait();
|
|
|
|
}
|
|
|
|
|
2018-01-26 18:09:30 +03:00
|
|
|
void WebRenderAPI::Capture() {
|
|
|
|
uint8_t bits = 3; // TODO: get from JavaScript
|
|
|
|
const char* path = "wr-capture"; // TODO: get from JavaScript
|
|
|
|
wr_api_capture(mDocHandle, path, bits);
|
|
|
|
}
|
|
|
|
|
2019-05-31 03:31:39 +03:00
|
|
|
void WebRenderAPI::SetCompositionRecorder(
|
|
|
|
RefPtr<layers::WebRenderCompositionRecorder>&& aRecorder) {
|
|
|
|
class SetCompositionRecorderEvent final : public RendererEvent {
|
|
|
|
public:
|
|
|
|
explicit SetCompositionRecorderEvent(
|
|
|
|
RefPtr<layers::WebRenderCompositionRecorder>&& aRecorder)
|
|
|
|
: mRecorder(std::move(aRecorder)) {
|
|
|
|
MOZ_COUNT_CTOR(SetCompositionRecorderEvent);
|
|
|
|
}
|
|
|
|
|
|
|
|
~SetCompositionRecorderEvent() {
|
|
|
|
MOZ_COUNT_DTOR(SetCompositionRecorderEvent);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Run(RenderThread& aRenderThread, WindowId aWindowId) override {
|
|
|
|
MOZ_ASSERT(mRecorder);
|
|
|
|
|
|
|
|
aRenderThread.SetCompositionRecorderForWindow(aWindowId,
|
|
|
|
std::move(mRecorder));
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
RefPtr<layers::WebRenderCompositionRecorder> mRecorder;
|
|
|
|
};
|
|
|
|
|
|
|
|
auto event = MakeUnique<SetCompositionRecorderEvent>(std::move(aRecorder));
|
|
|
|
RunOnRenderThread(std::move(event));
|
|
|
|
}
|
2017-10-06 20:06:10 +03:00
|
|
|
void TransactionBuilder::Clear() { wr_resource_updates_clear(mTxn); }
|
2018-01-26 18:09:30 +03:00
|
|
|
|
2018-01-29 16:33:39 +03:00
|
|
|
void TransactionBuilder::Notify(wr::Checkpoint aWhen,
|
|
|
|
UniquePtr<NotificationHandler> aEvent) {
|
2018-05-26 18:09:21 +03:00
|
|
|
wr_transaction_notify(mTxn, aWhen,
|
|
|
|
reinterpret_cast<uintptr_t>(aEvent.release()));
|
2017-09-04 14:59:36 +03:00
|
|
|
}
|
|
|
|
|
2018-09-24 18:53:36 +03:00
|
|
|
void TransactionBuilder::AddImage(ImageKey key,
|
|
|
|
const ImageDescriptor& aDescriptor,
|
|
|
|
wr::Vec<uint8_t>& aBytes) {
|
|
|
|
wr_resource_updates_add_image(mTxn, key, &aDescriptor, &aBytes.inner);
|
|
|
|
}
|
|
|
|
|
2018-01-29 16:33:39 +03:00
|
|
|
void TransactionBuilder::AddBlobImage(BlobImageKey key,
|
|
|
|
const ImageDescriptor& aDescriptor,
|
|
|
|
wr::Vec<uint8_t>& aBytes) {
|
2018-05-26 18:09:21 +03:00
|
|
|
wr_resource_updates_add_blob_image(mTxn, key, &aDescriptor, &aBytes.inner);
|
2017-03-27 14:44:52 +03:00
|
|
|
}
|
|
|
|
|
2019-05-29 01:03:54 +03:00
|
|
|
void TransactionBuilder::AddExternalImage(ImageKey key,
|
|
|
|
const ImageDescriptor& aDescriptor,
|
|
|
|
ExternalImageId aExtID,
|
|
|
|
wr::ExternalImageType aImageType,
|
|
|
|
uint8_t aChannelIndex) {
|
2018-05-26 18:09:21 +03:00
|
|
|
wr_resource_updates_add_external_image(mTxn, key, &aDescriptor, aExtID,
|
2019-05-29 01:03:54 +03:00
|
|
|
&aImageType, aChannelIndex);
|
2017-03-02 04:22:40 +03:00
|
|
|
}
|
|
|
|
|
2018-01-29 16:33:39 +03:00
|
|
|
void TransactionBuilder::AddExternalImageBuffer(
|
|
|
|
ImageKey aKey, const ImageDescriptor& aDescriptor,
|
|
|
|
ExternalImageId aHandle) {
|
2017-07-28 15:08:11 +03:00
|
|
|
auto channelIndex = 0;
|
2019-05-29 01:03:54 +03:00
|
|
|
AddExternalImage(aKey, aDescriptor, aHandle, wr::ExternalImageType::Buffer(),
|
|
|
|
channelIndex);
|
2017-09-04 14:59:12 +03:00
|
|
|
}
|
|
|
|
|
2018-01-29 16:33:39 +03:00
|
|
|
void TransactionBuilder::UpdateImageBuffer(ImageKey aKey,
|
|
|
|
const ImageDescriptor& aDescriptor,
|
|
|
|
wr::Vec<uint8_t>& aBytes) {
|
2017-07-28 15:08:11 +03:00
|
|
|
wr_resource_updates_update_image(mTxn, aKey, &aDescriptor, &aBytes.inner);
|
2017-01-16 17:22:47 +03:00
|
|
|
}
|
|
|
|
|
2018-11-24 02:33:49 +03:00
|
|
|
void TransactionBuilder::UpdateBlobImage(BlobImageKey aKey,
|
2018-01-29 16:33:39 +03:00
|
|
|
const ImageDescriptor& aDescriptor,
|
|
|
|
wr::Vec<uint8_t>& aBytes,
|
2018-11-24 02:33:49 +03:00
|
|
|
const wr::LayoutIntRect& aDirtyRect) {
|
2018-05-26 18:09:21 +03:00
|
|
|
wr_resource_updates_update_blob_image(mTxn, aKey, &aDescriptor, &aBytes.inner,
|
2017-08-03 23:38:33 +03:00
|
|
|
aDirtyRect);
|
2017-07-28 15:08:11 +03:00
|
|
|
}
|
|
|
|
|
2019-05-29 01:03:54 +03:00
|
|
|
void TransactionBuilder::UpdateExternalImage(ImageKey aKey,
|
|
|
|
const ImageDescriptor& aDescriptor,
|
|
|
|
ExternalImageId aExtID,
|
|
|
|
wr::ExternalImageType aImageType,
|
|
|
|
uint8_t aChannelIndex) {
|
2018-05-26 18:09:21 +03:00
|
|
|
wr_resource_updates_update_external_image(mTxn, aKey, &aDescriptor, aExtID,
|
2019-05-29 01:03:54 +03:00
|
|
|
&aImageType, aChannelIndex);
|
2017-07-28 15:08:11 +03:00
|
|
|
}
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2018-07-12 18:43:09 +03:00
|
|
|
void TransactionBuilder::UpdateExternalImageWithDirtyRect(
|
|
|
|
ImageKey aKey, const ImageDescriptor& aDescriptor, ExternalImageId aExtID,
|
2019-05-29 01:03:54 +03:00
|
|
|
wr::ExternalImageType aImageType, const wr::DeviceIntRect& aDirtyRect,
|
|
|
|
uint8_t aChannelIndex) {
|
2018-07-12 18:43:09 +03:00
|
|
|
wr_resource_updates_update_external_image_with_dirty_rect(
|
2019-05-29 01:03:54 +03:00
|
|
|
mTxn, aKey, &aDescriptor, aExtID, &aImageType, aChannelIndex, aDirtyRect);
|
2018-07-12 18:43:09 +03:00
|
|
|
}
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2018-11-24 02:33:49 +03:00
|
|
|
void TransactionBuilder::SetImageVisibleArea(BlobImageKey aKey,
|
2018-11-16 20:13:26 +03:00
|
|
|
const wr::DeviceIntRect& aArea) {
|
2018-11-24 02:33:49 +03:00
|
|
|
wr_resource_updates_set_blob_image_visible_area(mTxn, aKey, &aArea);
|
2018-07-19 23:33:05 +03:00
|
|
|
}
|
|
|
|
|
2018-01-29 16:33:39 +03:00
|
|
|
void TransactionBuilder::DeleteImage(ImageKey aKey) {
|
2018-05-26 18:09:21 +03:00
|
|
|
wr_resource_updates_delete_image(mTxn, aKey);
|
2017-01-16 17:22:47 +03:00
|
|
|
}
|
|
|
|
|
2018-11-24 02:33:49 +03:00
|
|
|
void TransactionBuilder::DeleteBlobImage(BlobImageKey aKey) {
|
|
|
|
wr_resource_updates_delete_blob_image(mTxn, aKey);
|
|
|
|
}
|
|
|
|
|
2018-01-29 16:33:39 +03:00
|
|
|
void TransactionBuilder::AddRawFont(wr::FontKey aKey, wr::Vec<uint8_t>& aBytes,
|
|
|
|
uint32_t aIndex) {
|
2018-05-26 18:09:21 +03:00
|
|
|
wr_resource_updates_add_raw_font(mTxn, aKey, &aBytes.inner, aIndex);
|
2017-01-16 17:22:47 +03:00
|
|
|
}
|
|
|
|
|
2018-01-29 16:33:39 +03:00
|
|
|
void TransactionBuilder::AddFontDescriptor(wr::FontKey aKey,
|
|
|
|
wr::Vec<uint8_t>& aBytes,
|
|
|
|
uint32_t aIndex) {
|
2018-05-26 18:09:21 +03:00
|
|
|
wr_resource_updates_add_font_descriptor(mTxn, aKey, &aBytes.inner, aIndex);
|
2017-11-07 04:19:46 +03:00
|
|
|
}
|
|
|
|
|
2018-01-29 16:33:39 +03:00
|
|
|
void TransactionBuilder::DeleteFont(wr::FontKey aKey) {
|
2018-05-26 18:09:21 +03:00
|
|
|
wr_resource_updates_delete_font(mTxn, aKey);
|
2017-01-16 17:22:47 +03:00
|
|
|
}
|
|
|
|
|
2018-01-29 16:33:39 +03:00
|
|
|
void TransactionBuilder::AddFontInstance(
|
|
|
|
wr::FontInstanceKey aKey, wr::FontKey aFontKey, float aGlyphSize,
|
|
|
|
const wr::FontInstanceOptions* aOptions,
|
|
|
|
const wr::FontInstancePlatformOptions* aPlatformOptions,
|
|
|
|
wr::Vec<uint8_t>& aVariations) {
|
2018-05-26 18:09:21 +03:00
|
|
|
wr_resource_updates_add_font_instance(mTxn, aKey, aFontKey, aGlyphSize,
|
2017-09-21 06:18:23 +03:00
|
|
|
aOptions, aPlatformOptions,
|
|
|
|
&aVariations.inner);
|
2017-08-30 20:45:11 +03:00
|
|
|
}
|
|
|
|
|
2018-01-29 16:33:39 +03:00
|
|
|
void TransactionBuilder::DeleteFontInstance(wr::FontInstanceKey aKey) {
|
2018-05-26 18:09:21 +03:00
|
|
|
wr_resource_updates_delete_font_instance(mTxn, aKey);
|
2017-08-30 20:45:11 +03:00
|
|
|
}
|
|
|
|
|
2017-07-28 02:05:56 +03:00
|
|
|
class FrameStartTime : public RendererEvent {
|
|
|
|
public:
|
|
|
|
explicit FrameStartTime(const TimeStamp& aTime) : mTime(aTime) {
|
|
|
|
MOZ_COUNT_CTOR(FrameStartTime);
|
|
|
|
}
|
|
|
|
|
2019-04-11 15:36:51 +03:00
|
|
|
virtual ~FrameStartTime() { MOZ_COUNT_DTOR(FrameStartTime); }
|
2017-07-28 02:05:56 +03:00
|
|
|
|
2019-04-11 15:36:51 +03:00
|
|
|
void Run(RenderThread& aRenderThread, WindowId aWindowId) override {
|
2017-07-28 02:05:56 +03:00
|
|
|
auto renderer = aRenderThread.GetRenderer(aWindowId);
|
|
|
|
if (renderer) {
|
|
|
|
renderer->SetFrameStartTime(mTime);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
TimeStamp mTime;
|
|
|
|
};
|
|
|
|
|
|
|
|
void WebRenderAPI::SetFrameStartTime(const TimeStamp& aTime) {
|
|
|
|
auto event = MakeUnique<FrameStartTime>(aTime);
|
2018-05-30 22:15:35 +03:00
|
|
|
RunOnRenderThread(std::move(event));
|
2017-07-28 02:05:56 +03:00
|
|
|
}
|
|
|
|
|
2017-01-28 00:08:17 +03:00
|
|
|
void WebRenderAPI::RunOnRenderThread(UniquePtr<RendererEvent> aEvent) {
|
2017-01-17 22:46:31 +03:00
|
|
|
auto event = reinterpret_cast<uintptr_t>(aEvent.release());
|
2017-08-09 15:46:24 +03:00
|
|
|
wr_api_send_external_event(mDocHandle, event);
|
2017-01-16 17:22:47 +03:00
|
|
|
}
|
|
|
|
|
2017-05-15 22:13:31 +03:00
|
|
|
DisplayListBuilder::DisplayListBuilder(PipelineId aId,
|
2017-10-05 05:31:51 +03:00
|
|
|
const wr::LayoutSize& aContentSize,
|
2019-03-22 21:28:42 +03:00
|
|
|
size_t aCapacity, RenderRoot aRenderRoot)
|
2019-01-09 06:27:07 +03:00
|
|
|
: mCurrentSpaceAndClipChain(wr::RootScrollNodeWithChain()),
|
2019-03-22 21:28:42 +03:00
|
|
|
mActiveFixedPosTracker(nullptr),
|
|
|
|
mPipelineId(aId),
|
|
|
|
mContentSize(aContentSize),
|
|
|
|
mRenderRoot(aRenderRoot),
|
|
|
|
mSendSubBuilderDisplayList(aRenderRoot == wr::RenderRoot::Default) {
|
2017-01-13 13:25:07 +03:00
|
|
|
MOZ_COUNT_CTOR(DisplayListBuilder);
|
2017-10-05 05:31:51 +03:00
|
|
|
mWrState = wr_state_new(aId, aContentSize, aCapacity);
|
2017-01-13 13:25:07 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
DisplayListBuilder::~DisplayListBuilder() {
|
|
|
|
MOZ_COUNT_DTOR(DisplayListBuilder);
|
2017-01-17 17:32:25 +03:00
|
|
|
wr_state_delete(mWrState);
|
2017-01-13 13:25:07 +03:00
|
|
|
}
|
|
|
|
|
2017-10-06 20:06:10 +03:00
|
|
|
void DisplayListBuilder::Save() { wr_dp_save(mWrState); }
|
|
|
|
void DisplayListBuilder::Restore() { wr_dp_restore(mWrState); }
|
|
|
|
void DisplayListBuilder::ClearSave() { wr_dp_clear_save(mWrState); }
|
2018-07-19 22:30:30 +03:00
|
|
|
|
2019-03-22 21:28:42 +03:00
|
|
|
DisplayListBuilder& DisplayListBuilder::CreateSubBuilder(
|
|
|
|
const wr::LayoutSize& aContentSize, size_t aCapacity,
|
|
|
|
wr::RenderRoot aRenderRoot) {
|
|
|
|
MOZ_ASSERT(mRenderRoot == wr::RenderRoot::Default);
|
|
|
|
MOZ_ASSERT(!mSubBuilders[aRenderRoot]);
|
|
|
|
mSubBuilders[aRenderRoot] = MakeUnique<DisplayListBuilder>(
|
|
|
|
mPipelineId, aContentSize, aCapacity, aRenderRoot);
|
|
|
|
return *mSubBuilders[aRenderRoot];
|
|
|
|
}
|
|
|
|
|
|
|
|
DisplayListBuilder& DisplayListBuilder::SubBuilder(RenderRoot aRenderRoot) {
|
|
|
|
if (aRenderRoot == mRenderRoot) {
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
return *mSubBuilders[aRenderRoot];
|
|
|
|
}
|
|
|
|
|
|
|
|
bool DisplayListBuilder::HasSubBuilder(RenderRoot aRenderRoot) {
|
|
|
|
if (aRenderRoot == RenderRoot::Default) {
|
|
|
|
MOZ_ASSERT(mRenderRoot == RenderRoot::Default);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return !!mSubBuilders[aRenderRoot];
|
|
|
|
}
|
|
|
|
|
2018-07-19 22:30:30 +03:00
|
|
|
usize DisplayListBuilder::Dump(usize aIndent, const Maybe<usize>& aStart,
|
|
|
|
const Maybe<usize>& aEnd) {
|
|
|
|
return wr_dump_display_list(mWrState, aIndent, aStart.ptrOr(nullptr),
|
|
|
|
aEnd.ptrOr(nullptr));
|
|
|
|
}
|
2017-10-06 20:06:10 +03:00
|
|
|
|
2017-07-19 01:32:46 +03:00
|
|
|
void DisplayListBuilder::Finalize(wr::LayoutSize& aOutContentSize,
|
2017-05-15 22:13:31 +03:00
|
|
|
BuiltDisplayList& aOutDisplayList) {
|
2017-03-03 18:45:29 +03:00
|
|
|
wr_api_finalize_builder(mWrState, &aOutContentSize, &aOutDisplayList.dl_desc,
|
2017-05-15 22:13:31 +03:00
|
|
|
&aOutDisplayList.dl.inner);
|
2017-03-01 17:10:53 +03:00
|
|
|
}
|
|
|
|
|
2019-03-22 21:28:42 +03:00
|
|
|
void DisplayListBuilder::Finalize(
|
|
|
|
layers::RenderRootDisplayListData& aOutTransaction) {
|
|
|
|
MOZ_ASSERT(mRenderRoot == wr::RenderRoot::Default);
|
|
|
|
wr::VecU8 dl;
|
|
|
|
wr_api_finalize_builder(SubBuilder(aOutTransaction.mRenderRoot).mWrState,
|
|
|
|
&aOutTransaction.mContentSize,
|
|
|
|
&aOutTransaction.mDLDesc, &dl.inner);
|
2019-03-22 21:29:04 +03:00
|
|
|
aOutTransaction.mDL.emplace(dl.inner.data, dl.inner.length,
|
|
|
|
dl.inner.capacity);
|
2019-03-22 21:28:42 +03:00
|
|
|
dl.inner.capacity = 0;
|
|
|
|
dl.inner.data = nullptr;
|
|
|
|
}
|
|
|
|
|
2019-01-09 06:27:07 +03:00
|
|
|
Maybe<wr::WrSpatialId> DisplayListBuilder::PushStackingContext(
|
2019-01-23 04:08:34 +03:00
|
|
|
const wr::StackingContextParams& aParams, const wr::LayoutRect& aBounds,
|
2018-09-23 04:19:52 +03:00
|
|
|
const wr::RasterSpace& aRasterSpace) {
|
2018-09-14 17:42:20 +03:00
|
|
|
MOZ_ASSERT(mClipChainLeaf.isNothing(),
|
|
|
|
"Non-empty leaf from clip chain given, but not used with SC!");
|
|
|
|
|
2017-07-19 01:32:46 +03:00
|
|
|
wr::LayoutTransform matrix;
|
2019-01-23 04:08:34 +03:00
|
|
|
const gfx::Matrix4x4* transform = aParams.mTransformPtr;
|
|
|
|
if (transform) {
|
|
|
|
matrix = ToLayoutTransform(*transform);
|
2017-03-29 12:23:08 +03:00
|
|
|
}
|
2019-01-23 04:08:34 +03:00
|
|
|
const wr::LayoutTransform* maybeTransform = transform ? &matrix : nullptr;
|
2018-11-29 22:22:37 +03:00
|
|
|
WRDL_LOG("PushStackingContext b=%s t=%s\n", mWrState,
|
|
|
|
Stringify(aBounds).c_str(),
|
2019-01-23 04:08:34 +03:00
|
|
|
transform ? Stringify(*transform).c_str() : "none");
|
2018-05-08 16:16:26 +03:00
|
|
|
|
2019-01-09 06:27:07 +03:00
|
|
|
auto spatialId = wr_dp_push_stacking_context(
|
2019-01-23 04:08:34 +03:00
|
|
|
mWrState, aBounds, mCurrentSpaceAndClipChain.space, &aParams,
|
|
|
|
maybeTransform, aParams.mFilters.Elements(), aParams.mFilters.Length(),
|
2019-02-26 09:16:36 +03:00
|
|
|
aParams.mFilterDatas.Elements(), aParams.mFilterDatas.Length(),
|
|
|
|
aRasterSpace);
|
2019-01-09 06:27:07 +03:00
|
|
|
|
|
|
|
return spatialId.id != 0 ? Some(spatialId) : Nothing();
|
2017-03-29 12:23:08 +03:00
|
|
|
}
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2018-05-16 17:47:08 +03:00
|
|
|
void DisplayListBuilder::PopStackingContext(bool aIsReferenceFrame) {
|
2017-08-28 21:20:25 +03:00
|
|
|
WRDL_LOG("PopStackingContext\n", mWrState);
|
2018-05-16 17:47:08 +03:00
|
|
|
wr_dp_pop_stacking_context(mWrState, aIsReferenceFrame);
|
2017-01-13 13:25:07 +03:00
|
|
|
}
|
|
|
|
|
2018-05-08 16:08:39 +03:00
|
|
|
wr::WrClipChainId DisplayListBuilder::DefineClipChain(
|
2019-05-01 20:35:44 +03:00
|
|
|
const nsTArray<wr::WrClipId>& aClips, bool aParentWithCurrentChain) {
|
2019-04-18 16:03:26 +03:00
|
|
|
const uint64_t* parent = nullptr;
|
2019-05-01 20:35:44 +03:00
|
|
|
if (aParentWithCurrentChain &&
|
|
|
|
mCurrentSpaceAndClipChain.clip_chain != wr::ROOT_CLIP_CHAIN) {
|
|
|
|
parent = &mCurrentSpaceAndClipChain.clip_chain;
|
2019-04-18 16:03:26 +03:00
|
|
|
}
|
2019-02-06 07:35:37 +03:00
|
|
|
uint64_t clipchainId = wr_dp_define_clipchain(
|
2019-04-18 16:03:26 +03:00
|
|
|
mWrState, parent, aClips.Elements(), aClips.Length());
|
2019-02-06 07:35:37 +03:00
|
|
|
WRDL_LOG("DefineClipChain id=%" PRIu64 " clips=%zu\n", mWrState, clipchainId,
|
2018-11-26 05:32:15 +03:00
|
|
|
aClips.Length());
|
2018-05-08 16:08:39 +03:00
|
|
|
return wr::WrClipChainId{clipchainId};
|
|
|
|
}
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2018-05-08 16:08:39 +03:00
|
|
|
wr::WrClipId DisplayListBuilder::DefineClip(
|
2019-01-09 06:27:07 +03:00
|
|
|
const Maybe<wr::WrSpaceAndClip>& aParent, const wr::LayoutRect& aClipRect,
|
2017-10-04 00:51:49 +03:00
|
|
|
const nsTArray<wr::ComplexClipRegion>* aComplex,
|
2019-03-03 00:48:06 +03:00
|
|
|
const wr::ImageMask* aMask) {
|
2019-01-09 06:27:07 +03:00
|
|
|
WrClipId clipId;
|
|
|
|
if (aParent) {
|
|
|
|
clipId = wr_dp_define_clip_with_parent_clip(
|
|
|
|
mWrState, aParent.ptr(), aClipRect,
|
|
|
|
aComplex ? aComplex->Elements() : nullptr,
|
|
|
|
aComplex ? aComplex->Length() : 0, aMask);
|
|
|
|
} else {
|
|
|
|
clipId = wr_dp_define_clip_with_parent_clip_chain(
|
|
|
|
mWrState, &mCurrentSpaceAndClipChain, aClipRect,
|
|
|
|
aComplex ? aComplex->Elements() : nullptr,
|
|
|
|
aComplex ? aComplex->Length() : 0, aMask);
|
|
|
|
}
|
|
|
|
|
2018-05-08 16:08:39 +03:00
|
|
|
WRDL_LOG("DefineClip id=%zu p=%s r=%s m=%p b=%s complex=%zu\n", mWrState,
|
2019-01-09 06:27:07 +03:00
|
|
|
clipId.id, aParent ? Stringify(aParent->clip.id).c_str() : "(nil)",
|
2017-10-24 22:45:57 +03:00
|
|
|
Stringify(aClipRect).c_str(), aMask,
|
2017-08-08 22:43:17 +03:00
|
|
|
aMask ? Stringify(aMask->rect).c_str() : "none",
|
|
|
|
aComplex ? aComplex->Length() : 0);
|
|
|
|
|
2019-01-09 06:27:07 +03:00
|
|
|
return clipId;
|
2017-10-25 22:05:20 +03:00
|
|
|
}
|
|
|
|
|
2019-01-09 06:27:07 +03:00
|
|
|
wr::WrSpatialId DisplayListBuilder::DefineStickyFrame(
|
2017-09-21 17:11:39 +03:00
|
|
|
const wr::LayoutRect& aContentRect, const float* aTopMargin,
|
2017-10-31 16:17:22 +03:00
|
|
|
const float* aRightMargin, const float* aBottomMargin,
|
|
|
|
const float* aLeftMargin, const StickyOffsetBounds& aVerticalBounds,
|
2017-11-07 18:16:48 +03:00
|
|
|
const StickyOffsetBounds& aHorizontalBounds,
|
|
|
|
const wr::LayoutVector2D& aAppliedOffset) {
|
2019-01-09 06:27:07 +03:00
|
|
|
auto spatialId = wr_dp_define_sticky_frame(
|
|
|
|
mWrState, mCurrentSpaceAndClipChain.space, aContentRect, aTopMargin,
|
|
|
|
aRightMargin, aBottomMargin, aLeftMargin, aVerticalBounds,
|
|
|
|
aHorizontalBounds, aAppliedOffset);
|
|
|
|
|
2018-03-02 00:49:54 +03:00
|
|
|
WRDL_LOG("DefineSticky id=%zu c=%s t=%s r=%s b=%s l=%s v=%s h=%s a=%s\n",
|
2019-01-09 06:27:07 +03:00
|
|
|
mWrState, spatialId.id, Stringify(aContentRect).c_str(),
|
2017-10-31 16:17:22 +03:00
|
|
|
aTopMargin ? Stringify(*aTopMargin).c_str() : "none",
|
|
|
|
aRightMargin ? Stringify(*aRightMargin).c_str() : "none",
|
|
|
|
aBottomMargin ? Stringify(*aBottomMargin).c_str() : "none",
|
|
|
|
aLeftMargin ? Stringify(*aLeftMargin).c_str() : "none",
|
|
|
|
Stringify(aVerticalBounds).c_str(),
|
2017-11-07 18:16:48 +03:00
|
|
|
Stringify(aHorizontalBounds).c_str(),
|
|
|
|
Stringify(aAppliedOffset).c_str());
|
2019-01-09 06:27:07 +03:00
|
|
|
|
|
|
|
return spatialId;
|
2017-09-21 17:11:39 +03:00
|
|
|
}
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2019-01-09 06:27:07 +03:00
|
|
|
Maybe<wr::WrSpaceAndClip> DisplayListBuilder::GetScrollIdForDefinedScrollLayer(
|
2018-11-01 23:15:46 +03:00
|
|
|
layers::ScrollableLayerGuid::ViewID aViewId) const {
|
|
|
|
if (aViewId == layers::ScrollableLayerGuid::NULL_SCROLL_ID) {
|
2018-11-23 22:49:56 +03:00
|
|
|
return Some(wr::RootScrollNode());
|
2018-01-22 21:29:06 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
auto it = mScrollIds.find(aViewId);
|
|
|
|
if (it == mScrollIds.end()) {
|
|
|
|
return Nothing();
|
|
|
|
}
|
|
|
|
|
|
|
|
return Some(it->second);
|
2017-08-30 21:51:19 +03:00
|
|
|
}
|
|
|
|
|
2019-01-09 06:27:07 +03:00
|
|
|
wr::WrSpaceAndClip DisplayListBuilder::DefineScrollLayer(
|
2018-11-01 23:15:46 +03:00
|
|
|
const layers::ScrollableLayerGuid::ViewID& aViewId,
|
2019-01-09 06:27:07 +03:00
|
|
|
const Maybe<wr::WrSpaceAndClip>& aParent,
|
2019-02-22 00:06:25 +03:00
|
|
|
const wr::LayoutRect& aContentRect, const wr::LayoutRect& aClipRect,
|
|
|
|
const wr::LayoutPoint& aScrollOffset) {
|
2018-01-22 21:29:06 +03:00
|
|
|
auto it = mScrollIds.find(aViewId);
|
|
|
|
if (it != mScrollIds.end()) {
|
|
|
|
return it->second;
|
2017-06-16 22:12:24 +03:00
|
|
|
}
|
2018-01-22 21:29:06 +03:00
|
|
|
|
|
|
|
// We haven't defined aViewId before, so let's define it now.
|
2019-01-17 19:43:08 +03:00
|
|
|
wr::WrSpaceAndClip defaultParent = wr::RootScrollNode();
|
|
|
|
// Note: we are currently ignoring the clipId on the stack here
|
|
|
|
defaultParent.space = mCurrentSpaceAndClipChain.space;
|
|
|
|
|
2019-01-09 06:27:07 +03:00
|
|
|
auto spaceAndClip = wr_dp_define_scroll_layer(
|
2019-01-17 19:43:08 +03:00
|
|
|
mWrState, aViewId, aParent ? aParent.ptr() : &defaultParent, aContentRect,
|
2019-02-22 00:06:25 +03:00
|
|
|
aClipRect, aScrollOffset);
|
2017-08-30 21:51:19 +03:00
|
|
|
|
2018-05-08 16:08:39 +03:00
|
|
|
WRDL_LOG("DefineScrollLayer id=%" PRIu64 "/%zu p=%s co=%s cl=%s\n", mWrState,
|
2019-01-09 06:27:07 +03:00
|
|
|
aViewId, spaceAndClip.space.id,
|
|
|
|
aParent ? Stringify(aParent->space.id).c_str() : "(nil)",
|
2018-05-08 16:08:39 +03:00
|
|
|
Stringify(aContentRect).c_str(), Stringify(aClipRect).c_str());
|
2017-02-14 21:34:15 +03:00
|
|
|
|
2019-01-09 06:27:07 +03:00
|
|
|
mScrollIds[aViewId] = spaceAndClip;
|
|
|
|
return spaceAndClip;
|
2017-06-08 18:34:01 +03:00
|
|
|
}
|
|
|
|
|
2017-07-19 01:32:46 +03:00
|
|
|
void DisplayListBuilder::PushRect(const wr::LayoutRect& aBounds,
|
|
|
|
const wr::LayoutRect& aClip,
|
2017-09-21 09:41:38 +03:00
|
|
|
bool aIsBackfaceVisible,
|
2017-07-19 01:32:46 +03:00
|
|
|
const wr::ColorF& aColor) {
|
2018-09-14 17:42:20 +03:00
|
|
|
wr::LayoutRect clip = MergeClipLeaf(aClip);
|
2017-08-28 21:20:25 +03:00
|
|
|
WRDL_LOG("PushRect b=%s cl=%s c=%s\n", mWrState, Stringify(aBounds).c_str(),
|
2017-05-29 18:40:49 +03:00
|
|
|
Stringify(clip).c_str(), Stringify(aColor).c_str());
|
2019-01-09 06:27:07 +03:00
|
|
|
wr_dp_push_rect(mWrState, aBounds, clip, aIsBackfaceVisible,
|
|
|
|
&mCurrentSpaceAndClipChain, aColor);
|
|
|
|
}
|
|
|
|
|
|
|
|
void DisplayListBuilder::PushRoundedRect(const wr::LayoutRect& aBounds,
|
|
|
|
const wr::LayoutRect& aClip,
|
|
|
|
bool aIsBackfaceVisible,
|
|
|
|
const wr::ColorF& aColor) {
|
|
|
|
wr::LayoutRect clip = MergeClipLeaf(aClip);
|
|
|
|
WRDL_LOG("PushRoundedRect b=%s cl=%s c=%s\n", mWrState,
|
|
|
|
Stringify(aBounds).c_str(), Stringify(clip).c_str(),
|
|
|
|
Stringify(aColor).c_str());
|
|
|
|
|
|
|
|
AutoTArray<wr::ComplexClipRegion, 1> clips;
|
|
|
|
clips.AppendElement(wr::SimpleRadii(aBounds, aBounds.size.width / 2));
|
|
|
|
// TODO: use `mCurrentSpaceAndClipChain.clip_chain` as a parent?
|
|
|
|
auto clipId = DefineClip(Nothing(), aBounds, &clips, nullptr);
|
|
|
|
auto spaceAndClip = WrSpaceAndClip{mCurrentSpaceAndClipChain.space, clipId};
|
|
|
|
|
|
|
|
wr_dp_push_rect_with_parent_clip(mWrState, aBounds, clip, aIsBackfaceVisible,
|
|
|
|
&spaceAndClip, aColor);
|
2017-01-13 13:25:07 +03:00
|
|
|
}
|
|
|
|
|
Bug 1536121 - rearchitect the webrender display-list. r=gw
disclaimer: this isn't an *amazing* cleanup, but more of a major step that
unlocks the ability to do more minor cleanups and refinements. There's some
messy things and inconsistencies here and there, but we can hopefully iron
them out over time.
1. The primary change here is to move from
struct { common_fields, enum(specific_fields) }
to
enum (maybe_common_fields, specific_fields)
most notably this drops the common fields from a ton of things
that don't need them PopXXX, SetXXX, ClipChain, etc.
2. Additionally some types have had some redundant states shaved off,
for instance, rect no longer has *both* bounds and a clip_rect, as
the intersection of the two can be used. This was done a bit conservatively
as some adjustments will need to be done to the backend to fully eliminate
some states, and this can be done more incrementally.
2.5. As a minor side-effect of 2, we now early-reject some primitives whose
bounds and clip_rect are disjoint.
3. A HitTest display item has been added, which is just a Rect without
color. In addition to the minor space wins from this, this makes it much
easier to debug display lists
4. Adds a bunch of comments to the display list, making it easier to understand
things.
The end result of all these changes is a significantly smaller and easier to
understand display list. Especially on pages like gmail which have so many
clip chains. However this ultimately just makes text an even greater percentage
of pages (often 70-80%).
Differential Revision: https://phabricator.services.mozilla.com/D27439
--HG--
extra : moz-landing-system : lando
2019-04-23 20:29:58 +03:00
|
|
|
void DisplayListBuilder::PushHitTest(const wr::LayoutRect& aBounds,
|
|
|
|
const wr::LayoutRect& aClip,
|
|
|
|
bool aIsBackfaceVisible) {
|
|
|
|
wr::LayoutRect clip = MergeClipLeaf(aClip);
|
|
|
|
WRDL_LOG("PushHitTest b=%s cl=%s\n", mWrState, Stringify(aBounds).c_str(),
|
|
|
|
Stringify(clip).c_str());
|
|
|
|
wr_dp_push_hit_test(mWrState, aBounds, clip, aIsBackfaceVisible,
|
|
|
|
&mCurrentSpaceAndClipChain);
|
|
|
|
}
|
|
|
|
|
2017-10-31 18:31:00 +03:00
|
|
|
void DisplayListBuilder::PushClearRect(const wr::LayoutRect& aBounds) {
|
2018-09-14 17:42:20 +03:00
|
|
|
wr::LayoutRect clip = MergeClipLeaf(aBounds);
|
|
|
|
WRDL_LOG("PushClearRect b=%s c=%s\n", mWrState, Stringify(aBounds).c_str(),
|
|
|
|
Stringify(clip).c_str());
|
2019-01-09 06:27:07 +03:00
|
|
|
wr_dp_push_clear_rect(mWrState, aBounds, clip, &mCurrentSpaceAndClipChain);
|
|
|
|
}
|
|
|
|
|
|
|
|
void DisplayListBuilder::PushClearRectWithComplexRegion(
|
|
|
|
const wr::LayoutRect& aBounds, const wr::ComplexClipRegion& aRegion) {
|
|
|
|
wr::LayoutRect clip = MergeClipLeaf(aBounds);
|
|
|
|
WRDL_LOG("PushClearRectWithComplexRegion b=%s c=%s\n", mWrState,
|
|
|
|
Stringify(aBounds).c_str(), Stringify(clip).c_str());
|
|
|
|
|
|
|
|
AutoTArray<wr::ComplexClipRegion, 1> clips;
|
|
|
|
auto clipId = DefineClip(Nothing(), aBounds, &clips, nullptr);
|
|
|
|
auto spaceAndClip = WrSpaceAndClip{mCurrentSpaceAndClipChain.space, clipId};
|
|
|
|
|
|
|
|
wr_dp_push_clear_rect_with_parent_clip(mWrState, aBounds, clip,
|
|
|
|
&spaceAndClip);
|
2017-10-31 18:31:00 +03:00
|
|
|
}
|
|
|
|
|
2017-07-19 01:32:46 +03:00
|
|
|
void DisplayListBuilder::PushLinearGradient(
|
|
|
|
const wr::LayoutRect& aBounds, const wr::LayoutRect& aClip,
|
|
|
|
bool aIsBackfaceVisible, const wr::LayoutPoint& aStartPoint,
|
2017-07-19 08:47:07 +03:00
|
|
|
const wr::LayoutPoint& aEndPoint, const nsTArray<wr::GradientStop>& aStops,
|
2017-07-19 01:32:46 +03:00
|
|
|
wr::ExtendMode aExtendMode, const wr::LayoutSize aTileSize,
|
|
|
|
const wr::LayoutSize aTileSpacing) {
|
2019-01-09 06:27:07 +03:00
|
|
|
wr_dp_push_linear_gradient(
|
|
|
|
mWrState, aBounds, MergeClipLeaf(aClip), aIsBackfaceVisible,
|
|
|
|
&mCurrentSpaceAndClipChain, aStartPoint, aEndPoint, aStops.Elements(),
|
|
|
|
aStops.Length(), aExtendMode, aTileSize, aTileSpacing);
|
2017-02-17 03:51:32 +03:00
|
|
|
}
|
|
|
|
|
2017-07-19 01:32:46 +03:00
|
|
|
void DisplayListBuilder::PushRadialGradient(
|
|
|
|
const wr::LayoutRect& aBounds, const wr::LayoutRect& aClip,
|
|
|
|
bool aIsBackfaceVisible, const wr::LayoutPoint& aCenter,
|
2017-07-19 08:47:07 +03:00
|
|
|
const wr::LayoutSize& aRadius, const nsTArray<wr::GradientStop>& aStops,
|
2017-07-19 01:32:46 +03:00
|
|
|
wr::ExtendMode aExtendMode, const wr::LayoutSize aTileSize,
|
|
|
|
const wr::LayoutSize aTileSpacing) {
|
2019-01-09 06:27:07 +03:00
|
|
|
wr_dp_push_radial_gradient(
|
|
|
|
mWrState, aBounds, MergeClipLeaf(aClip), aIsBackfaceVisible,
|
|
|
|
&mCurrentSpaceAndClipChain, aCenter, aRadius, aStops.Elements(),
|
|
|
|
aStops.Length(), aExtendMode, aTileSize, aTileSpacing);
|
2017-02-17 03:51:32 +03:00
|
|
|
}
|
|
|
|
|
2017-07-19 01:32:46 +03:00
|
|
|
void DisplayListBuilder::PushImage(
|
|
|
|
const wr::LayoutRect& aBounds, const wr::LayoutRect& aClip,
|
2017-02-14 21:34:15 +03:00
|
|
|
bool aIsBackfaceVisible, wr::ImageRendering aFilter, wr::ImageKey aImage,
|
2018-08-21 19:36:48 +03:00
|
|
|
bool aPremultipliedAlpha, const wr::ColorF& aColor) {
|
2017-07-19 01:32:46 +03:00
|
|
|
wr::LayoutSize size;
|
|
|
|
size.width = aBounds.size.width;
|
|
|
|
size.height = aBounds.size.height;
|
2018-09-14 17:42:20 +03:00
|
|
|
PushImage(aBounds, aClip, aIsBackfaceVisible, size, size, aFilter, aImage,
|
|
|
|
aPremultipliedAlpha, aColor);
|
2017-04-07 09:53:16 +03:00
|
|
|
}
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2017-07-19 01:32:46 +03:00
|
|
|
void DisplayListBuilder::PushImage(
|
|
|
|
const wr::LayoutRect& aBounds, const wr::LayoutRect& aClip,
|
|
|
|
bool aIsBackfaceVisible, const wr::LayoutSize& aStretchSize,
|
|
|
|
const wr::LayoutSize& aTileSpacing, wr::ImageRendering aFilter,
|
2018-08-21 19:36:48 +03:00
|
|
|
wr::ImageKey aImage, bool aPremultipliedAlpha, const wr::ColorF& aColor) {
|
2018-09-14 17:42:20 +03:00
|
|
|
wr::LayoutRect clip = MergeClipLeaf(aClip);
|
2017-08-28 21:20:25 +03:00
|
|
|
WRDL_LOG("PushImage b=%s cl=%s s=%s t=%s\n", mWrState,
|
|
|
|
Stringify(aBounds).c_str(), Stringify(clip).c_str(),
|
2018-09-14 17:42:20 +03:00
|
|
|
Stringify(aStretchSize).c_str(), Stringify(aTileSpacing).c_str());
|
2019-01-09 06:27:07 +03:00
|
|
|
wr_dp_push_image(mWrState, aBounds, clip, aIsBackfaceVisible,
|
|
|
|
&mCurrentSpaceAndClipChain, aStretchSize, aTileSpacing,
|
|
|
|
aFilter, aImage, aPremultipliedAlpha, aColor);
|
2017-01-13 13:25:07 +03:00
|
|
|
}
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2017-07-19 01:32:46 +03:00
|
|
|
void DisplayListBuilder::PushYCbCrPlanarImage(
|
|
|
|
const wr::LayoutRect& aBounds, const wr::LayoutRect& aClip,
|
2017-04-29 00:00:57 +03:00
|
|
|
bool aIsBackfaceVisible, wr::ImageKey aImageChannel0,
|
|
|
|
wr::ImageKey aImageChannel1, wr::ImageKey aImageChannel2,
|
2017-06-28 02:20:36 +03:00
|
|
|
wr::WrColorDepth aColorDepth, wr::WrYuvColorSpace aColorSpace,
|
2017-06-01 15:57:10 +03:00
|
|
|
wr::ImageRendering aRendering) {
|
2017-04-29 00:00:57 +03:00
|
|
|
wr_dp_push_yuv_planar_image(mWrState, aBounds, MergeClipLeaf(aClip),
|
2019-01-09 06:27:07 +03:00
|
|
|
aIsBackfaceVisible, &mCurrentSpaceAndClipChain,
|
|
|
|
aImageChannel0, aImageChannel1, aImageChannel2,
|
|
|
|
aColorDepth, aColorSpace, aRendering);
|
2017-04-29 00:00:57 +03:00
|
|
|
}
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2017-07-19 01:32:46 +03:00
|
|
|
void DisplayListBuilder::PushNV12Image(
|
|
|
|
const wr::LayoutRect& aBounds, const wr::LayoutRect& aClip,
|
2017-04-29 00:00:57 +03:00
|
|
|
bool aIsBackfaceVisible, wr::ImageKey aImageChannel0,
|
2018-09-26 17:58:25 +03:00
|
|
|
wr::ImageKey aImageChannel1, wr::WrColorDepth aColorDepth,
|
2017-06-28 02:20:36 +03:00
|
|
|
wr::WrYuvColorSpace aColorSpace, wr::ImageRendering aRendering) {
|
2017-04-29 00:00:57 +03:00
|
|
|
wr_dp_push_yuv_NV12_image(mWrState, aBounds, MergeClipLeaf(aClip),
|
2019-01-09 06:27:07 +03:00
|
|
|
aIsBackfaceVisible, &mCurrentSpaceAndClipChain,
|
|
|
|
aImageChannel0, aImageChannel1, aColorDepth,
|
|
|
|
aColorSpace, aRendering);
|
2017-04-29 00:00:57 +03:00
|
|
|
}
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2017-07-19 01:32:46 +03:00
|
|
|
void DisplayListBuilder::PushYCbCrInterleavedImage(
|
|
|
|
const wr::LayoutRect& aBounds, const wr::LayoutRect& aClip,
|
2017-05-18 17:59:07 +03:00
|
|
|
bool aIsBackfaceVisible, wr::ImageKey aImageChannel0,
|
2017-06-28 02:20:36 +03:00
|
|
|
wr::WrColorDepth aColorDepth, wr::WrYuvColorSpace aColorSpace,
|
2017-06-01 15:57:10 +03:00
|
|
|
wr::ImageRendering aRendering) {
|
2017-05-18 17:59:07 +03:00
|
|
|
wr_dp_push_yuv_interleaved_image(mWrState, aBounds, MergeClipLeaf(aClip),
|
2019-01-09 06:27:07 +03:00
|
|
|
aIsBackfaceVisible,
|
|
|
|
&mCurrentSpaceAndClipChain, aImageChannel0,
|
2018-09-26 17:58:25 +03:00
|
|
|
aColorDepth, aColorSpace, aRendering);
|
2017-05-18 17:59:07 +03:00
|
|
|
}
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2017-07-19 01:32:46 +03:00
|
|
|
void DisplayListBuilder::PushIFrame(const wr::LayoutRect& aBounds,
|
2017-09-21 09:41:38 +03:00
|
|
|
bool aIsBackfaceVisible,
|
2018-05-18 17:31:18 +03:00
|
|
|
PipelineId aPipeline,
|
|
|
|
bool aIgnoreMissingPipeline) {
|
2018-09-14 17:42:20 +03:00
|
|
|
wr_dp_push_iframe(mWrState, aBounds, MergeClipLeaf(aBounds),
|
2019-01-09 06:27:07 +03:00
|
|
|
aIsBackfaceVisible, &mCurrentSpaceAndClipChain, aPipeline,
|
|
|
|
aIgnoreMissingPipeline);
|
2017-01-13 13:25:07 +03:00
|
|
|
}
|
|
|
|
|
2017-07-19 01:32:46 +03:00
|
|
|
void DisplayListBuilder::PushBorder(const wr::LayoutRect& aBounds,
|
|
|
|
const wr::LayoutRect& aClip,
|
2017-09-21 09:41:38 +03:00
|
|
|
bool aIsBackfaceVisible,
|
2018-09-18 16:01:36 +03:00
|
|
|
const wr::LayoutSideOffsets& aWidths,
|
2017-07-19 08:56:20 +03:00
|
|
|
const Range<const wr::BorderSide>& aSides,
|
2018-08-30 01:35:03 +03:00
|
|
|
const wr::BorderRadius& aRadius,
|
|
|
|
wr::AntialiasBorder aAntialias) {
|
2017-07-01 02:22:25 +03:00
|
|
|
MOZ_ASSERT(aSides.length() == 4);
|
|
|
|
if (aSides.length() != 4) {
|
|
|
|
return;
|
|
|
|
}
|
2018-09-14 17:42:20 +03:00
|
|
|
wr_dp_push_border(mWrState, aBounds, MergeClipLeaf(aClip), aIsBackfaceVisible,
|
2019-01-09 06:27:07 +03:00
|
|
|
&mCurrentSpaceAndClipChain, aAntialias, aWidths, aSides[0],
|
|
|
|
aSides[1], aSides[2], aSides[3], aRadius);
|
2017-03-13 06:46:03 +03:00
|
|
|
}
|
|
|
|
|
2017-07-19 01:32:46 +03:00
|
|
|
void DisplayListBuilder::PushBorderImage(
|
|
|
|
const wr::LayoutRect& aBounds, const wr::LayoutRect& aClip,
|
2018-09-18 16:01:36 +03:00
|
|
|
bool aIsBackfaceVisible, const wr::LayoutSideOffsets& aWidths,
|
2018-11-16 20:13:26 +03:00
|
|
|
wr::ImageKey aImage, const int32_t aWidth, const int32_t aHeight,
|
|
|
|
const wr::SideOffsets2D<int32_t>& aSlice,
|
2018-01-04 21:23:34 +03:00
|
|
|
const wr::SideOffsets2D<float>& aOutset,
|
2017-07-19 08:56:20 +03:00
|
|
|
const wr::RepeatMode& aRepeatHorizontal,
|
|
|
|
const wr::RepeatMode& aRepeatVertical) {
|
2018-09-14 17:42:20 +03:00
|
|
|
wr_dp_push_border_image(mWrState, aBounds, MergeClipLeaf(aClip),
|
2019-01-09 06:27:07 +03:00
|
|
|
aIsBackfaceVisible, &mCurrentSpaceAndClipChain,
|
|
|
|
aWidths, aImage, aWidth, aHeight, aSlice, aOutset,
|
|
|
|
aRepeatHorizontal, aRepeatVertical);
|
2017-01-13 13:25:07 +03:00
|
|
|
}
|
|
|
|
|
2017-07-19 01:32:46 +03:00
|
|
|
void DisplayListBuilder::PushBorderGradient(
|
|
|
|
const wr::LayoutRect& aBounds, const wr::LayoutRect& aClip,
|
2018-09-18 16:01:36 +03:00
|
|
|
bool aIsBackfaceVisible, const wr::LayoutSideOffsets& aWidths,
|
2018-11-16 20:13:26 +03:00
|
|
|
const int32_t aWidth, const int32_t aHeight,
|
|
|
|
const wr::SideOffsets2D<int32_t>& aSlice,
|
2017-07-19 01:32:46 +03:00
|
|
|
const wr::LayoutPoint& aStartPoint, const wr::LayoutPoint& aEndPoint,
|
2017-07-19 08:47:07 +03:00
|
|
|
const nsTArray<wr::GradientStop>& aStops, wr::ExtendMode aExtendMode,
|
2018-01-04 21:23:34 +03:00
|
|
|
const wr::SideOffsets2D<float>& aOutset) {
|
2019-01-09 06:27:07 +03:00
|
|
|
wr_dp_push_border_gradient(
|
|
|
|
mWrState, aBounds, MergeClipLeaf(aClip), aIsBackfaceVisible,
|
|
|
|
&mCurrentSpaceAndClipChain, aWidths, aWidth, aHeight, aSlice, aStartPoint,
|
|
|
|
aEndPoint, aStops.Elements(), aStops.Length(), aExtendMode, aOutset);
|
2017-04-10 12:27:30 +03:00
|
|
|
}
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2017-07-19 01:32:46 +03:00
|
|
|
void DisplayListBuilder::PushBorderRadialGradient(
|
|
|
|
const wr::LayoutRect& aBounds, const wr::LayoutRect& aClip,
|
2018-09-18 16:01:36 +03:00
|
|
|
bool aIsBackfaceVisible, const wr::LayoutSideOffsets& aWidths,
|
2017-07-19 01:32:46 +03:00
|
|
|
const wr::LayoutPoint& aCenter, const wr::LayoutSize& aRadius,
|
2017-07-19 08:47:07 +03:00
|
|
|
const nsTArray<wr::GradientStop>& aStops, wr::ExtendMode aExtendMode,
|
2018-01-04 21:23:34 +03:00
|
|
|
const wr::SideOffsets2D<float>& aOutset) {
|
2019-01-09 06:27:07 +03:00
|
|
|
wr_dp_push_border_radial_gradient(
|
|
|
|
mWrState, aBounds, MergeClipLeaf(aClip), aIsBackfaceVisible,
|
|
|
|
&mCurrentSpaceAndClipChain, aWidths, aCenter, aRadius, aStops.Elements(),
|
|
|
|
aStops.Length(), aExtendMode, aOutset);
|
2017-04-10 12:27:30 +03:00
|
|
|
}
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2017-07-19 01:32:46 +03:00
|
|
|
void DisplayListBuilder::PushText(const wr::LayoutRect& aBounds,
|
|
|
|
const wr::LayoutRect& aClip,
|
2017-09-21 09:41:38 +03:00
|
|
|
bool aIsBackfaceVisible,
|
2017-10-04 20:49:51 +03:00
|
|
|
const wr::ColorF& aColor,
|
2017-08-30 20:45:11 +03:00
|
|
|
wr::FontInstanceKey aFontKey,
|
2017-07-19 01:53:09 +03:00
|
|
|
Range<const wr::GlyphInstance> aGlyphBuffer,
|
2017-08-30 20:45:11 +03:00
|
|
|
const wr::GlyphOptions* aGlyphOptions) {
|
2018-09-14 17:42:20 +03:00
|
|
|
wr_dp_push_text(mWrState, aBounds, MergeClipLeaf(aClip), aIsBackfaceVisible,
|
2019-01-09 06:27:07 +03:00
|
|
|
&mCurrentSpaceAndClipChain, aColor, aFontKey,
|
|
|
|
&aGlyphBuffer[0], aGlyphBuffer.length(), aGlyphOptions);
|
2017-01-13 13:25:07 +03:00
|
|
|
}
|
|
|
|
|
Bug 1357545 - handle text-shadows/decorations with webrender (layers-free) r=jrmuizel
This replaces our DrawTargetCapture hack with a similar but more powerful TextDrawTarget
hack. The old design had several limitations:
* It couldn't handle shadows
* It couldn't handle selections
* It couldn't handle font/color changes in a single text-run
* It couldn't handle decorations (underline, overline, line-through)
Mostly this was a consequence of the fact that it only modified the start and end
of the rendering algorithm, and therefore couldn't distinguish draw calls for different
parts of the text.
This new design is based on a similar principle as DrawTargetCapture, but also passes
down the TextDrawTarget in the drawing arguments, so that the drawing algorithm can
notify us of changes in phase (e.g. "now we're doing underlines"). This also lets us
directly pass data to TextDrawTarget when possible (as is done for shadows and selections).
In doing this, I also improved the logic copied from ContainsOnlyColoredGlyphs to handle
changes in font/color mid-text-run (which can happen because of font fallback).
The end result is:
* We handle all shadows natively
* We handle all selections natively
* We handle all decorations natively
* We handle font/color changes in a single text-run
* Although we still hackily intercept draw calls
* But we don't need to buffer commands, reducing total memcopies
In addition, this change integrates webrender's PushTextShadow and PushLine APIs,
which were designed for this use case. This is only done in the layerless path;
WebrenderTextLayer continues to be semantically limited, as we aren't actively
maintaining non-layers-free webrender anymore.
This also doesn't modify TextLayers, to minimize churn. In theory they can be
augmented to support the richer semantics that TextDrawTarget has, but there's
little motivation since the API is largely unused with this change.
MozReview-Commit-ID: 4IjTsSW335h
--HG--
extra : rebase_source : d69f69648ade5c7a8e6bb756f4b8ab9e2543e576
2017-06-19 17:58:28 +03:00
|
|
|
void DisplayListBuilder::PushLine(const wr::LayoutRect& aClip,
|
2017-09-21 09:41:38 +03:00
|
|
|
bool aIsBackfaceVisible,
|
Bug 1357545 - handle text-shadows/decorations with webrender (layers-free) r=jrmuizel
This replaces our DrawTargetCapture hack with a similar but more powerful TextDrawTarget
hack. The old design had several limitations:
* It couldn't handle shadows
* It couldn't handle selections
* It couldn't handle font/color changes in a single text-run
* It couldn't handle decorations (underline, overline, line-through)
Mostly this was a consequence of the fact that it only modified the start and end
of the rendering algorithm, and therefore couldn't distinguish draw calls for different
parts of the text.
This new design is based on a similar principle as DrawTargetCapture, but also passes
down the TextDrawTarget in the drawing arguments, so that the drawing algorithm can
notify us of changes in phase (e.g. "now we're doing underlines"). This also lets us
directly pass data to TextDrawTarget when possible (as is done for shadows and selections).
In doing this, I also improved the logic copied from ContainsOnlyColoredGlyphs to handle
changes in font/color mid-text-run (which can happen because of font fallback).
The end result is:
* We handle all shadows natively
* We handle all selections natively
* We handle all decorations natively
* We handle font/color changes in a single text-run
* Although we still hackily intercept draw calls
* But we don't need to buffer commands, reducing total memcopies
In addition, this change integrates webrender's PushTextShadow and PushLine APIs,
which were designed for this use case. This is only done in the layerless path;
WebrenderTextLayer continues to be semantically limited, as we aren't actively
maintaining non-layers-free webrender anymore.
This also doesn't modify TextLayers, to minimize churn. In theory they can be
augmented to support the richer semantics that TextDrawTarget has, but there's
little motivation since the API is largely unused with this change.
MozReview-Commit-ID: 4IjTsSW335h
--HG--
extra : rebase_source : d69f69648ade5c7a8e6bb756f4b8ab9e2543e576
2017-06-19 17:58:28 +03:00
|
|
|
const wr::Line& aLine) {
|
2018-09-14 17:42:20 +03:00
|
|
|
wr::LayoutRect clip = MergeClipLeaf(aClip);
|
2019-01-09 06:27:07 +03:00
|
|
|
wr_dp_push_line(mWrState, &clip, aIsBackfaceVisible,
|
|
|
|
&mCurrentSpaceAndClipChain, &aLine.bounds,
|
2018-09-14 17:42:20 +03:00
|
|
|
aLine.wavyLineThickness, aLine.orientation, &aLine.color,
|
|
|
|
aLine.style);
|
Bug 1357545 - handle text-shadows/decorations with webrender (layers-free) r=jrmuizel
This replaces our DrawTargetCapture hack with a similar but more powerful TextDrawTarget
hack. The old design had several limitations:
* It couldn't handle shadows
* It couldn't handle selections
* It couldn't handle font/color changes in a single text-run
* It couldn't handle decorations (underline, overline, line-through)
Mostly this was a consequence of the fact that it only modified the start and end
of the rendering algorithm, and therefore couldn't distinguish draw calls for different
parts of the text.
This new design is based on a similar principle as DrawTargetCapture, but also passes
down the TextDrawTarget in the drawing arguments, so that the drawing algorithm can
notify us of changes in phase (e.g. "now we're doing underlines"). This also lets us
directly pass data to TextDrawTarget when possible (as is done for shadows and selections).
In doing this, I also improved the logic copied from ContainsOnlyColoredGlyphs to handle
changes in font/color mid-text-run (which can happen because of font fallback).
The end result is:
* We handle all shadows natively
* We handle all selections natively
* We handle all decorations natively
* We handle font/color changes in a single text-run
* Although we still hackily intercept draw calls
* But we don't need to buffer commands, reducing total memcopies
In addition, this change integrates webrender's PushTextShadow and PushLine APIs,
which were designed for this use case. This is only done in the layerless path;
WebrenderTextLayer continues to be semantically limited, as we aren't actively
maintaining non-layers-free webrender anymore.
This also doesn't modify TextLayers, to minimize churn. In theory they can be
augmented to support the richer semantics that TextDrawTarget has, but there's
little motivation since the API is largely unused with this change.
MozReview-Commit-ID: 4IjTsSW335h
--HG--
extra : rebase_source : d69f69648ade5c7a8e6bb756f4b8ab9e2543e576
2017-06-19 17:58:28 +03:00
|
|
|
}
|
|
|
|
|
2017-10-04 21:54:37 +03:00
|
|
|
void DisplayListBuilder::PushShadow(const wr::LayoutRect& aRect,
|
|
|
|
const wr::LayoutRect& aClip,
|
|
|
|
bool aIsBackfaceVisible,
|
2019-05-10 23:13:31 +03:00
|
|
|
const wr::Shadow& aShadow,
|
|
|
|
bool aShouldInflate) {
|
2019-04-16 02:13:49 +03:00
|
|
|
// Local clip_rects are translated inside of shadows, as they are assumed to
|
|
|
|
// be part of the element drawing itself, and not a parent frame clipping it.
|
|
|
|
// As such, it is not sound to apply the MergeClipLeaf optimization inside of
|
|
|
|
// shadows. So we disable the optimization when we encounter a shadow.
|
|
|
|
// Shadows don't span frames, so we don't have to worry about MergeClipLeaf
|
|
|
|
// being re-enabled mid-shadow. The optimization is restored in PopAllShadows.
|
|
|
|
SuspendClipLeafMerging();
|
|
|
|
wr_dp_push_shadow(mWrState, aRect, aClip, aIsBackfaceVisible,
|
2019-05-25 20:46:15 +03:00
|
|
|
&mCurrentSpaceAndClipChain, aShadow, aShouldInflate);
|
Bug 1357545 - handle text-shadows/decorations with webrender (layers-free) r=jrmuizel
This replaces our DrawTargetCapture hack with a similar but more powerful TextDrawTarget
hack. The old design had several limitations:
* It couldn't handle shadows
* It couldn't handle selections
* It couldn't handle font/color changes in a single text-run
* It couldn't handle decorations (underline, overline, line-through)
Mostly this was a consequence of the fact that it only modified the start and end
of the rendering algorithm, and therefore couldn't distinguish draw calls for different
parts of the text.
This new design is based on a similar principle as DrawTargetCapture, but also passes
down the TextDrawTarget in the drawing arguments, so that the drawing algorithm can
notify us of changes in phase (e.g. "now we're doing underlines"). This also lets us
directly pass data to TextDrawTarget when possible (as is done for shadows and selections).
In doing this, I also improved the logic copied from ContainsOnlyColoredGlyphs to handle
changes in font/color mid-text-run (which can happen because of font fallback).
The end result is:
* We handle all shadows natively
* We handle all selections natively
* We handle all decorations natively
* We handle font/color changes in a single text-run
* Although we still hackily intercept draw calls
* But we don't need to buffer commands, reducing total memcopies
In addition, this change integrates webrender's PushTextShadow and PushLine APIs,
which were designed for this use case. This is only done in the layerless path;
WebrenderTextLayer continues to be semantically limited, as we aren't actively
maintaining non-layers-free webrender anymore.
This also doesn't modify TextLayers, to minimize churn. In theory they can be
augmented to support the richer semantics that TextDrawTarget has, but there's
little motivation since the API is largely unused with this change.
MozReview-Commit-ID: 4IjTsSW335h
--HG--
extra : rebase_source : d69f69648ade5c7a8e6bb756f4b8ab9e2543e576
2017-06-19 17:58:28 +03:00
|
|
|
}
|
|
|
|
|
2019-04-16 02:13:49 +03:00
|
|
|
void DisplayListBuilder::PopAllShadows() {
|
|
|
|
wr_dp_pop_all_shadows(mWrState);
|
|
|
|
ResumeClipLeafMerging();
|
|
|
|
}
|
|
|
|
|
|
|
|
void DisplayListBuilder::SuspendClipLeafMerging() {
|
|
|
|
if (mClipChainLeaf) {
|
|
|
|
// No one should reinitialize mClipChainLeaf while we're suspended
|
|
|
|
MOZ_ASSERT(!mSuspendedClipChainLeaf);
|
|
|
|
|
|
|
|
mSuspendedClipChainLeaf = mClipChainLeaf;
|
|
|
|
mSuspendedSpaceAndClipChain = Some(mCurrentSpaceAndClipChain);
|
|
|
|
|
|
|
|
auto clipId = DefineClip(Nothing(), *mClipChainLeaf);
|
2019-05-01 20:35:44 +03:00
|
|
|
auto clipChainId = DefineClipChain({clipId}, true);
|
2019-04-16 02:13:49 +03:00
|
|
|
|
|
|
|
mCurrentSpaceAndClipChain.clip_chain = clipChainId.id;
|
|
|
|
mClipChainLeaf = Nothing();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void DisplayListBuilder::ResumeClipLeafMerging() {
|
|
|
|
if (mSuspendedClipChainLeaf) {
|
|
|
|
mCurrentSpaceAndClipChain = *mSuspendedSpaceAndClipChain;
|
|
|
|
mClipChainLeaf = mSuspendedClipChainLeaf;
|
|
|
|
|
|
|
|
mSuspendedClipChainLeaf = Nothing();
|
|
|
|
mSuspendedSpaceAndClipChain = Nothing();
|
|
|
|
}
|
|
|
|
}
|
Bug 1357545 - handle text-shadows/decorations with webrender (layers-free) r=jrmuizel
This replaces our DrawTargetCapture hack with a similar but more powerful TextDrawTarget
hack. The old design had several limitations:
* It couldn't handle shadows
* It couldn't handle selections
* It couldn't handle font/color changes in a single text-run
* It couldn't handle decorations (underline, overline, line-through)
Mostly this was a consequence of the fact that it only modified the start and end
of the rendering algorithm, and therefore couldn't distinguish draw calls for different
parts of the text.
This new design is based on a similar principle as DrawTargetCapture, but also passes
down the TextDrawTarget in the drawing arguments, so that the drawing algorithm can
notify us of changes in phase (e.g. "now we're doing underlines"). This also lets us
directly pass data to TextDrawTarget when possible (as is done for shadows and selections).
In doing this, I also improved the logic copied from ContainsOnlyColoredGlyphs to handle
changes in font/color mid-text-run (which can happen because of font fallback).
The end result is:
* We handle all shadows natively
* We handle all selections natively
* We handle all decorations natively
* We handle font/color changes in a single text-run
* Although we still hackily intercept draw calls
* But we don't need to buffer commands, reducing total memcopies
In addition, this change integrates webrender's PushTextShadow and PushLine APIs,
which were designed for this use case. This is only done in the layerless path;
WebrenderTextLayer continues to be semantically limited, as we aren't actively
maintaining non-layers-free webrender anymore.
This also doesn't modify TextLayers, to minimize churn. In theory they can be
augmented to support the richer semantics that TextDrawTarget has, but there's
little motivation since the API is largely unused with this change.
MozReview-Commit-ID: 4IjTsSW335h
--HG--
extra : rebase_source : d69f69648ade5c7a8e6bb756f4b8ab9e2543e576
2017-06-19 17:58:28 +03:00
|
|
|
|
2017-07-19 01:32:46 +03:00
|
|
|
void DisplayListBuilder::PushBoxShadow(
|
|
|
|
const wr::LayoutRect& aRect, const wr::LayoutRect& aClip,
|
|
|
|
bool aIsBackfaceVisible, const wr::LayoutRect& aBoxBounds,
|
|
|
|
const wr::LayoutVector2D& aOffset, const wr::ColorF& aColor,
|
2017-02-16 21:23:22 +03:00
|
|
|
const float& aBlurRadius, const float& aSpreadRadius,
|
2017-10-24 09:44:29 +03:00
|
|
|
const wr::BorderRadius& aBorderRadius,
|
2017-07-19 10:28:58 +03:00
|
|
|
const wr::BoxShadowClipMode& aClipMode) {
|
2018-09-14 17:42:20 +03:00
|
|
|
wr_dp_push_box_shadow(mWrState, aRect, MergeClipLeaf(aClip),
|
2019-01-09 06:27:07 +03:00
|
|
|
aIsBackfaceVisible, &mCurrentSpaceAndClipChain,
|
|
|
|
aBoxBounds, aOffset, aColor, aBlurRadius, aSpreadRadius,
|
|
|
|
aBorderRadius, aClipMode);
|
2017-02-16 21:23:22 +03:00
|
|
|
}
|
|
|
|
|
2018-11-01 23:15:46 +03:00
|
|
|
Maybe<layers::ScrollableLayerGuid::ViewID>
|
Bug 1465935 - Fix hit-testing for fixed-pos items inside iframes. r=mstange
Without this patch, the scrollId for display items inside a fixed-pos
item end as the ASR of the item. In the case of fixed-pos items that are
inside iframes, the ASR is the outer document's root scrollframe. This
means that e.g. wheel-scrolling while over a fixed-pos item inside an
iframe ends up scrolling the outer document's root scrollframe instead
of the iframe's root scrollframe.
In the non-WR codepath, there some APZ machinery that walks up in the
HitTestingTreeNode tree from the hit result, looking to see if that node
has a fixed-pos ancestor, and if so, uses the fixed-pos item's target
APZ as the real hit result. This machinery doesn't exist in WR, because
we don't use the HitTestingTreeNode tree for hit-testing in APZ.
Instead, we need to make sure that the item tag for those display items
already has the appropriate scrollid set.
This patch accomplishes this by introducing a new RAII class that is
pushed into the wr::DisplayListBuilder while we are building display
items inside a nsDisplayFixedPosition, and allows the desired scroll id to
be set on the hit-testing display items.
This behaviour is exercised by test_group_wheelevents, which can now be
enabled with this fix.
MozReview-Commit-ID: L2erPVzJeql
--HG--
extra : rebase_source : 1db630513cb1dc16d4e38649812e81f62c8da99c
2018-06-07 20:06:33 +03:00
|
|
|
DisplayListBuilder::GetContainingFixedPosScrollTarget(
|
|
|
|
const ActiveScrolledRoot* aAsr) {
|
|
|
|
return mActiveFixedPosTracker
|
|
|
|
? mActiveFixedPosTracker->GetScrollTargetForASR(aAsr)
|
|
|
|
: Nothing();
|
|
|
|
}
|
|
|
|
|
2018-11-01 23:15:46 +03:00
|
|
|
void DisplayListBuilder::SetHitTestInfo(
|
|
|
|
const layers::ScrollableLayerGuid::ViewID& aScrollId,
|
2017-11-15 19:39:44 +03:00
|
|
|
gfx::CompositorHitTestInfo aHitInfo) {
|
2018-09-25 21:47:55 +03:00
|
|
|
static_assert(DoesCompositorHitTestInfoFitIntoBits<16>(),
|
|
|
|
"CompositorHitTestFlags MAX value has to be less than number "
|
|
|
|
"of bits in uint16_t");
|
|
|
|
|
|
|
|
wr_set_item_tag(mWrState, aScrollId,
|
|
|
|
static_cast<uint16_t>(aHitInfo.serialize()));
|
2017-11-15 19:39:44 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void DisplayListBuilder::ClearHitTestInfo() { wr_clear_item_tag(mWrState); }
|
|
|
|
|
Bug 1465935 - Fix hit-testing for fixed-pos items inside iframes. r=mstange
Without this patch, the scrollId for display items inside a fixed-pos
item end as the ASR of the item. In the case of fixed-pos items that are
inside iframes, the ASR is the outer document's root scrollframe. This
means that e.g. wheel-scrolling while over a fixed-pos item inside an
iframe ends up scrolling the outer document's root scrollframe instead
of the iframe's root scrollframe.
In the non-WR codepath, there some APZ machinery that walks up in the
HitTestingTreeNode tree from the hit result, looking to see if that node
has a fixed-pos ancestor, and if so, uses the fixed-pos item's target
APZ as the real hit result. This machinery doesn't exist in WR, because
we don't use the HitTestingTreeNode tree for hit-testing in APZ.
Instead, we need to make sure that the item tag for those display items
already has the appropriate scrollid set.
This patch accomplishes this by introducing a new RAII class that is
pushed into the wr::DisplayListBuilder while we are building display
items inside a nsDisplayFixedPosition, and allows the desired scroll id to
be set on the hit-testing display items.
This behaviour is exercised by test_group_wheelevents, which can now be
enabled with this fix.
MozReview-Commit-ID: L2erPVzJeql
--HG--
extra : rebase_source : 1db630513cb1dc16d4e38649812e81f62c8da99c
2018-06-07 20:06:33 +03:00
|
|
|
DisplayListBuilder::FixedPosScrollTargetTracker::FixedPosScrollTargetTracker(
|
|
|
|
DisplayListBuilder& aBuilder, const ActiveScrolledRoot* aAsr,
|
2018-11-01 23:15:46 +03:00
|
|
|
layers::ScrollableLayerGuid::ViewID aScrollId)
|
Bug 1465935 - Fix hit-testing for fixed-pos items inside iframes. r=mstange
Without this patch, the scrollId for display items inside a fixed-pos
item end as the ASR of the item. In the case of fixed-pos items that are
inside iframes, the ASR is the outer document's root scrollframe. This
means that e.g. wheel-scrolling while over a fixed-pos item inside an
iframe ends up scrolling the outer document's root scrollframe instead
of the iframe's root scrollframe.
In the non-WR codepath, there some APZ machinery that walks up in the
HitTestingTreeNode tree from the hit result, looking to see if that node
has a fixed-pos ancestor, and if so, uses the fixed-pos item's target
APZ as the real hit result. This machinery doesn't exist in WR, because
we don't use the HitTestingTreeNode tree for hit-testing in APZ.
Instead, we need to make sure that the item tag for those display items
already has the appropriate scrollid set.
This patch accomplishes this by introducing a new RAII class that is
pushed into the wr::DisplayListBuilder while we are building display
items inside a nsDisplayFixedPosition, and allows the desired scroll id to
be set on the hit-testing display items.
This behaviour is exercised by test_group_wheelevents, which can now be
enabled with this fix.
MozReview-Commit-ID: L2erPVzJeql
--HG--
extra : rebase_source : 1db630513cb1dc16d4e38649812e81f62c8da99c
2018-06-07 20:06:33 +03:00
|
|
|
: mParentTracker(aBuilder.mActiveFixedPosTracker),
|
|
|
|
mBuilder(aBuilder),
|
|
|
|
mAsr(aAsr),
|
|
|
|
mScrollId(aScrollId) {
|
|
|
|
aBuilder.mActiveFixedPosTracker = this;
|
|
|
|
}
|
|
|
|
|
|
|
|
DisplayListBuilder::FixedPosScrollTargetTracker::
|
|
|
|
~FixedPosScrollTargetTracker() {
|
|
|
|
mBuilder.mActiveFixedPosTracker = mParentTracker;
|
|
|
|
}
|
|
|
|
|
2018-11-01 23:15:46 +03:00
|
|
|
Maybe<layers::ScrollableLayerGuid::ViewID>
|
Bug 1465935 - Fix hit-testing for fixed-pos items inside iframes. r=mstange
Without this patch, the scrollId for display items inside a fixed-pos
item end as the ASR of the item. In the case of fixed-pos items that are
inside iframes, the ASR is the outer document's root scrollframe. This
means that e.g. wheel-scrolling while over a fixed-pos item inside an
iframe ends up scrolling the outer document's root scrollframe instead
of the iframe's root scrollframe.
In the non-WR codepath, there some APZ machinery that walks up in the
HitTestingTreeNode tree from the hit result, looking to see if that node
has a fixed-pos ancestor, and if so, uses the fixed-pos item's target
APZ as the real hit result. This machinery doesn't exist in WR, because
we don't use the HitTestingTreeNode tree for hit-testing in APZ.
Instead, we need to make sure that the item tag for those display items
already has the appropriate scrollid set.
This patch accomplishes this by introducing a new RAII class that is
pushed into the wr::DisplayListBuilder while we are building display
items inside a nsDisplayFixedPosition, and allows the desired scroll id to
be set on the hit-testing display items.
This behaviour is exercised by test_group_wheelevents, which can now be
enabled with this fix.
MozReview-Commit-ID: L2erPVzJeql
--HG--
extra : rebase_source : 1db630513cb1dc16d4e38649812e81f62c8da99c
2018-06-07 20:06:33 +03:00
|
|
|
DisplayListBuilder::FixedPosScrollTargetTracker::GetScrollTargetForASR(
|
|
|
|
const ActiveScrolledRoot* aAsr) {
|
|
|
|
return aAsr == mAsr ? Some(mScrollId) : Nothing();
|
|
|
|
}
|
|
|
|
|
2018-11-26 01:57:04 +03:00
|
|
|
already_AddRefed<gfxContext> DisplayListBuilder::GetTextContext(
|
|
|
|
wr::IpcResourceUpdateQueue& aResources,
|
|
|
|
const layers::StackingContextHelper& aSc,
|
2019-01-08 00:33:10 +03:00
|
|
|
layers::RenderRootStateManager* aManager, nsDisplayItem* aItem,
|
2018-11-26 01:57:04 +03:00
|
|
|
nsRect& aBounds, const gfx::Point& aDeviceOffset) {
|
|
|
|
if (!mCachedTextDT) {
|
|
|
|
mCachedTextDT = new layout::TextDrawTarget(*this, aResources, aSc, aManager,
|
|
|
|
aItem, aBounds);
|
|
|
|
mCachedContext = gfxContext::CreateOrNull(mCachedTextDT, aDeviceOffset);
|
|
|
|
} else {
|
|
|
|
mCachedTextDT->Reinitialize(aResources, aSc, aManager, aItem, aBounds);
|
|
|
|
mCachedContext->SetDeviceOffset(aDeviceOffset);
|
|
|
|
mCachedContext->SetMatrix(Matrix());
|
|
|
|
}
|
|
|
|
|
|
|
|
RefPtr<gfxContext> tmp = mCachedContext;
|
|
|
|
return tmp.forget();
|
|
|
|
}
|
|
|
|
|
2017-01-25 00:06:17 +03:00
|
|
|
} // namespace wr
|
|
|
|
} // namespace mozilla
|
2018-09-24 18:53:36 +03:00
|
|
|
|
|
|
|
extern "C" {
|
|
|
|
|
|
|
|
void wr_transaction_notification_notified(uintptr_t aHandler,
|
|
|
|
mozilla::wr::Checkpoint aWhen) {
|
|
|
|
auto handler = reinterpret_cast<mozilla::wr::NotificationHandler*>(aHandler);
|
|
|
|
handler->Notify(aWhen);
|
|
|
|
// TODO: it would be better to get a callback when the object is destroyed on
|
|
|
|
// the rust side and delete then.
|
|
|
|
delete handler;
|
|
|
|
}
|
|
|
|
|
2019-04-26 10:49:15 +03:00
|
|
|
void wr_register_thread_local_arena() {
|
|
|
|
#ifdef MOZ_MEMORY
|
|
|
|
jemalloc_thread_local_arena(true);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2018-09-24 18:53:36 +03:00
|
|
|
} // extern C
|