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
|
|
|
|
|
|
|
#include "gfxPrefs.h"
|
2017-05-29 18:40:49 +03:00
|
|
|
#include "LayersLogging.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"
|
2017-01-10 12:17:30 +03:00
|
|
|
|
2017-05-29 18:40:49 +03:00
|
|
|
#define WRDL_LOG(...)
|
2017-08-28 21:20:25 +03:00
|
|
|
//#define WRDL_LOG(...) printf_stderr("WRDL(%p): " __VA_ARGS__)
|
2018-01-06 17:52:57 +03:00
|
|
|
//#define WRDL_LOG(...) if (XRE_IsContentProcess()) printf_stderr("WRDL(%p): " __VA_ARGS__)
|
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;
|
|
|
|
|
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,
|
2017-08-12 08:41:56 +03:00
|
|
|
uint32_t* aMaxTextureSize,
|
2017-02-23 11:46:56 +03:00
|
|
|
bool* aUseANGLE,
|
2018-07-20 16:58:40 +03:00
|
|
|
bool* aUseDComp,
|
2017-01-11 15:51:27 +03:00
|
|
|
RefPtr<widget::CompositorWidget>&& aWidget,
|
2017-01-17 03:22:09 +03:00
|
|
|
layers::SynchronousTask* aTask,
|
2017-08-07 13:15:25 +03:00
|
|
|
LayoutDeviceIntSize aSize,
|
|
|
|
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)
|
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);
|
|
|
|
}
|
|
|
|
|
2017-01-17 03:22:09 +03:00
|
|
|
virtual void Run(RenderThread& aRenderThread, WindowId aWindowId) override
|
2017-01-10 12:17:30 +03:00
|
|
|
{
|
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();
|
2017-01-18 22:50:00 +03:00
|
|
|
|
2018-09-12 18:30:17 +03:00
|
|
|
bool supportLowPriorityTransactions = true; // TODO only for main windows.
|
2017-07-19 10:28:58 +03:00
|
|
|
wr::Renderer* wrRenderer = nullptr;
|
2018-09-12 18:30:17 +03:00
|
|
|
if (!wr_window_new(aWindowId, mSize.width, mSize.height, supportLowPriorityTransactions,
|
|
|
|
compositor->gl(),
|
2017-06-13 18:57:16 +03:00
|
|
|
aRenderThread.ThreadPool().Raw(),
|
2017-08-23 13:00:37 +03:00
|
|
|
mDocHandle, &wrRenderer,
|
2017-08-12 08:41:56 +03:00
|
|
|
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-11-24 14:58:24 +03:00
|
|
|
if (gfx::gfxVars::UseWebRenderProgramBinary()) {
|
|
|
|
wr_renderer_update_program_cache(wrRenderer, aRenderThread.ProgramCache()->Raw());
|
|
|
|
}
|
2017-03-01 12:08:56 +03:00
|
|
|
}
|
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;
|
2017-08-12 08:41:56 +03:00
|
|
|
uint32_t* mMaxTextureSize;
|
2017-02-23 11:46:56 +03:00
|
|
|
bool* mUseANGLE;
|
2018-07-20 16:58:40 +03:00
|
|
|
bool* mUseDComp;
|
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)
|
2017-01-25 00:06:17 +03:00
|
|
|
: mTask(aTask)
|
2017-01-11 15:51:27 +03:00
|
|
|
{
|
|
|
|
MOZ_COUNT_CTOR(RemoveRenderer);
|
|
|
|
}
|
2017-01-10 12:17:30 +03:00
|
|
|
|
2017-01-11 15:51:27 +03:00
|
|
|
~RemoveRenderer()
|
|
|
|
{
|
|
|
|
MOZ_COUNT_DTOR(RemoveRenderer);
|
|
|
|
}
|
2017-01-10 12:17:30 +03:00
|
|
|
|
2017-01-17 03:22:09 +03:00
|
|
|
virtual 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-01-12 14:23:59 +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-01-12 14:23:59 +03:00
|
|
|
{
|
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(gfx::Color aBgColor,
|
|
|
|
Epoch aEpoch,
|
|
|
|
mozilla::LayerSize aViewportSize,
|
|
|
|
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),
|
|
|
|
aViewportSize.width, aViewportSize.height,
|
|
|
|
pipeline_id,
|
|
|
|
content_size,
|
|
|
|
dl_descriptor,
|
|
|
|
&dl_data.inner);
|
|
|
|
}
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2018-01-29 16:33:35 +03:00
|
|
|
TransactionBuilder::SetWindowParameters(const LayoutDeviceIntSize& aWindowSize,
|
|
|
|
const LayoutDeviceIntRect& aDocumentRect)
|
2018-01-12 14:23:59 +03:00
|
|
|
{
|
2018-01-29 16:33:35 +03:00
|
|
|
wr::DeviceUintSize wrWindowSize;
|
|
|
|
wrWindowSize.width = aWindowSize.width;
|
|
|
|
wrWindowSize.height = aWindowSize.height;
|
|
|
|
wr::DeviceUintRect wrDocRect;
|
|
|
|
wrDocRect.origin.x = aDocumentRect.x;
|
|
|
|
wrDocRect.origin.y = aDocumentRect.y;
|
|
|
|
wrDocRect.size.width = aDocumentRect.width;
|
|
|
|
wrDocRect.size.height = aDocumentRect.height;
|
|
|
|
wr_transaction_set_window_parameters(mTxn, &wrWindowSize, &wrDocRect);
|
2018-01-12 14:23:59 +03:00
|
|
|
}
|
|
|
|
|
2018-01-17 19:19:39 +03:00
|
|
|
void
|
|
|
|
TransactionBuilder::UpdateScrollPosition(const wr::WrPipelineId& aPipelineId,
|
|
|
|
const layers::FrameMetrics::ViewID& aScrollId,
|
|
|
|
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,
|
|
|
|
const layers::FrameMetrics::ViewID& aScrollId,
|
|
|
|
const wr::LayoutPoint& aScrollPosition)
|
|
|
|
{
|
|
|
|
wr_transaction_scroll_layer(mTxn, aPipelineId, aScrollId, aScrollPosition);
|
|
|
|
}
|
2018-01-12 14:23:59 +03:00
|
|
|
|
2017-11-10 15:30:53 +03:00
|
|
|
/*static*/ already_AddRefed<WebRenderAPI>
|
2018-04-10 19:29:55 +03:00
|
|
|
WebRenderAPI::Create(layers::CompositorBridgeParent* aBridge,
|
2017-03-07 02:46:30 +03:00
|
|
|
RefPtr<widget::CompositorWidget>&& aWidget,
|
2018-04-10 19:29:55 +03:00
|
|
|
const wr::WrWindowId& aWindowId,
|
2017-03-07 02:46:30 +03:00
|
|
|
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;
|
2017-08-12 08:41:56 +03:00
|
|
|
uint32_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;
|
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 created
|
2017-01-11 15:51:27 +03:00
|
|
|
// on the render thread. If need be we could delay waiting on this task until
|
2017-08-09 15:46:24 +03:00
|
|
|
// the next time we need to access the DocumentHandle object.
|
2017-01-17 03:22:09 +03:00
|
|
|
layers::SynchronousTask task("Create Renderer");
|
2018-07-20 16:58:40 +03:00
|
|
|
auto event = MakeUnique<NewRenderer>(&docHandle, aBridge, &maxTextureSize, &useANGLE, &useDComp,
|
2018-05-30 22:15:35 +03:00
|
|
|
std::move(aWidget), &task, aSize,
|
2017-08-07 13:15:25 +03:00
|
|
|
&syncHandle);
|
2018-05-30 22:15:35 +03:00
|
|
|
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-07-20 16:58:40 +03:00
|
|
|
return RefPtr<WebRenderAPI>(new WebRenderAPI(docHandle, aWindowId, maxTextureSize, useANGLE, useDComp, syncHandle)).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-07-20 16:58:40 +03:00
|
|
|
RefPtr<WebRenderAPI> renderApi = new WebRenderAPI(docHandle, mId, mMaxTextureSize, mUseANGLE, mUseDComp, mSyncHandle);
|
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(LayoutDeviceIntSize aSize, int8_t aLayerIndex)
|
|
|
|
{
|
|
|
|
wr::DeviceUintSize wrSize;
|
|
|
|
wrSize.width = aSize.width;
|
|
|
|
wrSize.height = aSize.height;
|
|
|
|
wr::DocumentHandle* newDoc;
|
|
|
|
|
|
|
|
wr_api_create_document(mDocHandle, &newDoc, wrSize, aLayerIndex);
|
|
|
|
|
|
|
|
RefPtr<WebRenderAPI> api(new WebRenderAPI(newDoc, mId,
|
|
|
|
mMaxTextureSize,
|
|
|
|
mUseANGLE,
|
2018-07-20 16:58:40 +03:00
|
|
|
mUseDComp,
|
2018-01-29 16:33:35 +03:00
|
|
|
mSyncHandle));
|
|
|
|
api->mRootApi = this;
|
|
|
|
return api.forget();
|
|
|
|
}
|
|
|
|
|
2017-06-28 02:20:36 +03:00
|
|
|
wr::WrIdNamespace
|
2017-02-22 21:19:57 +03:00
|
|
|
WebRenderAPI::GetNamespace() {
|
2017-08-09 15:46:24 +03:00
|
|
|
return wr_api_get_namespace(mDocHandle);
|
2017-02-22 21:19:57 +03:00
|
|
|
}
|
|
|
|
|
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-01-12 14:23:59 +03:00
|
|
|
void
|
|
|
|
WebRenderAPI::SendTransaction(TransactionBuilder& aTxn)
|
|
|
|
{
|
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
|
|
|
}
|
|
|
|
|
2017-11-15 19:39:44 +03:00
|
|
|
bool
|
|
|
|
WebRenderAPI::HitTest(const wr::WorldPoint& aPoint,
|
|
|
|
wr::WrPipelineId& aOutPipelineId,
|
|
|
|
layers::FrameMetrics::ViewID& aOutScrollId,
|
|
|
|
gfx::CompositorHitTestInfo& aOutHitInfo)
|
|
|
|
{
|
2017-11-23 17:40:00 +03:00
|
|
|
static_assert(sizeof(gfx::CompositorHitTestInfo) == sizeof(uint16_t),
|
|
|
|
"CompositorHitTestInfo should be u16-sized");
|
2017-11-15 19:39:44 +03:00
|
|
|
return wr_api_hit_test(mDocHandle, aPoint,
|
2017-11-23 17:40:00 +03:00
|
|
|
&aOutPipelineId, &aOutScrollId, (uint16_t*)&aOutHitInfo);
|
2017-11-15 19:39:44 +03:00
|
|
|
}
|
|
|
|
|
2017-01-16 17:22:47 +03:00
|
|
|
void
|
2018-06-26 00:37:35 +03:00
|
|
|
WebRenderAPI::Readback(const TimeStamp& aStartTime,
|
|
|
|
gfx::IntSize size,
|
2017-01-25 07:29:34 +03:00
|
|
|
uint8_t *buffer,
|
|
|
|
uint32_t buffer_size)
|
|
|
|
{
|
|
|
|
class Readback : public RendererEvent
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
explicit Readback(layers::SynchronousTask* aTask,
|
2018-06-26 00:37:35 +03:00
|
|
|
TimeStamp aStartTime,
|
2017-01-25 07:29:34 +03:00
|
|
|
gfx::IntSize aSize, uint8_t *aBuffer, uint32_t aBufferSize)
|
|
|
|
: mTask(aTask)
|
2018-06-26 00:37:35 +03:00
|
|
|
, mStartTime(aStartTime)
|
2017-01-25 07:29:34 +03:00
|
|
|
, mSize(aSize)
|
|
|
|
, mBuffer(aBuffer)
|
|
|
|
, mBufferSize(aBufferSize)
|
|
|
|
{
|
|
|
|
MOZ_COUNT_CTOR(Readback);
|
|
|
|
}
|
|
|
|
|
|
|
|
~Readback()
|
|
|
|
{
|
|
|
|
MOZ_COUNT_DTOR(Readback);
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void Run(RenderThread& aRenderThread, WindowId aWindowId) override
|
|
|
|
{
|
2018-06-26 00:37:35 +03:00
|
|
|
aRenderThread.UpdateAndRender(aWindowId, mStartTime, /* aReadback */ true);
|
2017-07-19 10:28:58 +03:00
|
|
|
wr_renderer_readback(aRenderThread.GetRenderer(aWindowId)->GetRenderer(),
|
2017-03-20 19:10:40 +03:00
|
|
|
mSize.width, mSize.height, mBuffer, mBufferSize);
|
2017-01-25 07:29:34 +03:00
|
|
|
layers::AutoCompleteTask complete(mTask);
|
|
|
|
}
|
|
|
|
|
|
|
|
layers::SynchronousTask* mTask;
|
2018-06-26 00:37:35 +03:00
|
|
|
TimeStamp mStartTime;
|
2017-01-25 07:29:34 +03:00
|
|
|
gfx::IntSize mSize;
|
|
|
|
uint8_t *mBuffer;
|
|
|
|
uint32_t mBufferSize;
|
|
|
|
};
|
|
|
|
|
|
|
|
layers::SynchronousTask task("Readback");
|
2018-06-26 00:37:35 +03:00
|
|
|
auto event = MakeUnique<Readback>(&task, aStartTime, size, buffer, buffer_size);
|
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));
|
2017-03-07 13:37:28 +03:00
|
|
|
|
|
|
|
task.Wait();
|
|
|
|
}
|
|
|
|
|
2018-08-10 18:14:57 +03:00
|
|
|
void
|
|
|
|
WebRenderAPI::ClearAllCaches()
|
|
|
|
{
|
|
|
|
wr_api_clear_all_caches(mDocHandle);
|
|
|
|
}
|
|
|
|
|
2017-04-05 17:12:11 +03:00
|
|
|
void
|
|
|
|
WebRenderAPI::Pause()
|
|
|
|
{
|
|
|
|
class PauseEvent : public RendererEvent
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
explicit PauseEvent(layers::SynchronousTask* aTask)
|
|
|
|
: mTask(aTask)
|
|
|
|
{
|
|
|
|
MOZ_COUNT_CTOR(PauseEvent);
|
|
|
|
}
|
|
|
|
|
|
|
|
~PauseEvent()
|
|
|
|
{
|
|
|
|
MOZ_COUNT_DTOR(PauseEvent);
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void Run(RenderThread& aRenderThread, WindowId aWindowId) override
|
|
|
|
{
|
|
|
|
aRenderThread.Pause(aWindowId);
|
|
|
|
layers::AutoCompleteTask complete(mTask);
|
|
|
|
}
|
|
|
|
|
|
|
|
layers::SynchronousTask* mTask;
|
|
|
|
};
|
|
|
|
|
|
|
|
layers::SynchronousTask task("Pause");
|
|
|
|
auto event = MakeUnique<PauseEvent>(&task);
|
|
|
|
// 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 event.
|
2018-05-30 22:15:35 +03:00
|
|
|
RunOnRenderThread(std::move(event));
|
2017-04-05 17:12:11 +03:00
|
|
|
|
|
|
|
task.Wait();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
WebRenderAPI::Resume()
|
|
|
|
{
|
|
|
|
class ResumeEvent : public RendererEvent
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
explicit ResumeEvent(layers::SynchronousTask* aTask, bool* aResult)
|
|
|
|
: mTask(aTask)
|
|
|
|
, mResult(aResult)
|
|
|
|
{
|
|
|
|
MOZ_COUNT_CTOR(ResumeEvent);
|
|
|
|
}
|
|
|
|
|
|
|
|
~ResumeEvent()
|
|
|
|
{
|
|
|
|
MOZ_COUNT_DTOR(ResumeEvent);
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void Run(RenderThread& aRenderThread, WindowId aWindowId) override
|
|
|
|
{
|
|
|
|
*mResult = aRenderThread.Resume(aWindowId);
|
|
|
|
layers::AutoCompleteTask complete(mTask);
|
|
|
|
}
|
|
|
|
|
|
|
|
layers::SynchronousTask* mTask;
|
|
|
|
bool* mResult;
|
|
|
|
};
|
|
|
|
|
|
|
|
bool result = false;
|
|
|
|
layers::SynchronousTask task("Resume");
|
|
|
|
auto event = MakeUnique<ResumeEvent>(&task, &result);
|
|
|
|
// 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 event.
|
2018-05-30 22:15:35 +03:00
|
|
|
RunOnRenderThread(std::move(event));
|
2017-04-05 17:12:11 +03:00
|
|
|
|
|
|
|
task.Wait();
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2018-08-20 16:23:54 +03:00
|
|
|
void
|
|
|
|
WebRenderAPI::NotifyMemoryPressure()
|
|
|
|
{
|
|
|
|
wr_api_notify_memory_pressure(mDocHandle);
|
|
|
|
}
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
~WaitFlushedEvent()
|
|
|
|
{
|
|
|
|
MOZ_COUNT_DTOR(WaitFlushedEvent);
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void Run(RenderThread& aRenderThread, WindowId aWindowId) override
|
|
|
|
{
|
|
|
|
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
|
|
|
|
const char* border = "--------------------------\n";
|
|
|
|
printf("%s Capturing WR state to: %s\n%s", border, path, border);
|
|
|
|
wr_api_capture(mDocHandle, path, bits);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-09-04 14:59:36 +03:00
|
|
|
void
|
2018-01-29 16:33:39 +03:00
|
|
|
TransactionBuilder::Clear()
|
2017-09-04 14:59:36 +03:00
|
|
|
{
|
2018-05-26 18:09:21 +03:00
|
|
|
wr_resource_updates_clear(mTxn);
|
2017-09-04 14:59:36 +03:00
|
|
|
}
|
|
|
|
|
2017-03-27 14:44:52 +03:00
|
|
|
void
|
2018-01-29 16:33:39 +03:00
|
|
|
TransactionBuilder::AddImage(ImageKey key, const ImageDescriptor& aDescriptor,
|
|
|
|
wr::Vec<uint8_t>& aBytes)
|
2017-03-27 14:44:52 +03:00
|
|
|
{
|
2018-05-26 18:09:21 +03:00
|
|
|
wr_resource_updates_add_image(mTxn,
|
2017-09-04 14:59:12 +03:00
|
|
|
key,
|
|
|
|
&aDescriptor,
|
2017-09-14 19:48:55 +03:00
|
|
|
&aBytes.inner);
|
2017-03-27 14:44:52 +03:00
|
|
|
}
|
|
|
|
|
2017-03-02 04:22:40 +03:00
|
|
|
void
|
2018-01-29 16:33:39 +03:00
|
|
|
TransactionBuilder::AddBlobImage(ImageKey key, const ImageDescriptor& aDescriptor,
|
|
|
|
wr::Vec<uint8_t>& aBytes)
|
2017-03-02 04:22:40 +03:00
|
|
|
{
|
2018-05-26 18:09:21 +03:00
|
|
|
wr_resource_updates_add_blob_image(mTxn,
|
2017-09-04 14:59:12 +03:00
|
|
|
key,
|
|
|
|
&aDescriptor,
|
2017-09-14 19:48:55 +03:00
|
|
|
&aBytes.inner);
|
2017-03-02 04:22:40 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2018-01-29 16:33:39 +03:00
|
|
|
TransactionBuilder::AddExternalImage(ImageKey key,
|
|
|
|
const ImageDescriptor& aDescriptor,
|
|
|
|
ExternalImageId aExtID,
|
|
|
|
wr::WrExternalImageBufferType aBufferType,
|
|
|
|
uint8_t aChannelIndex)
|
2017-09-04 14:59:12 +03:00
|
|
|
{
|
2018-05-26 18:09:21 +03:00
|
|
|
wr_resource_updates_add_external_image(mTxn,
|
2017-09-04 14:59:12 +03:00
|
|
|
key,
|
|
|
|
&aDescriptor,
|
|
|
|
aExtID,
|
|
|
|
aBufferType,
|
|
|
|
aChannelIndex);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2018-01-29 16:33:39 +03:00
|
|
|
TransactionBuilder::AddExternalImageBuffer(ImageKey aKey,
|
|
|
|
const ImageDescriptor& aDescriptor,
|
|
|
|
ExternalImageId aHandle)
|
2017-01-16 17:22:47 +03:00
|
|
|
{
|
2017-07-28 15:08:11 +03:00
|
|
|
auto channelIndex = 0;
|
|
|
|
AddExternalImage(aKey, aDescriptor, aHandle,
|
|
|
|
wr::WrExternalImageBufferType::ExternalBuffer,
|
|
|
|
channelIndex);
|
2017-01-16 17:22:47 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2018-01-29 16:33:39 +03:00
|
|
|
TransactionBuilder::UpdateImageBuffer(ImageKey aKey,
|
|
|
|
const ImageDescriptor& aDescriptor,
|
|
|
|
wr::Vec<uint8_t>& aBytes)
|
2017-01-16 17:22:47 +03:00
|
|
|
{
|
2018-05-26 18:09:21 +03:00
|
|
|
wr_resource_updates_update_image(mTxn,
|
2017-09-04 14:59:12 +03:00
|
|
|
aKey,
|
|
|
|
&aDescriptor,
|
2017-09-14 19:48:55 +03:00
|
|
|
&aBytes.inner);
|
2017-01-16 17:22:47 +03:00
|
|
|
}
|
|
|
|
|
2017-07-28 15:08:11 +03:00
|
|
|
void
|
2018-01-29 16:33:39 +03:00
|
|
|
TransactionBuilder::UpdateBlobImage(ImageKey aKey,
|
|
|
|
const ImageDescriptor& aDescriptor,
|
|
|
|
wr::Vec<uint8_t>& aBytes,
|
|
|
|
const wr::DeviceUintRect& aDirtyRect)
|
2017-07-28 15:08:11 +03:00
|
|
|
{
|
2018-05-26 18:09:21 +03:00
|
|
|
wr_resource_updates_update_blob_image(mTxn,
|
2017-09-04 14:59:12 +03:00
|
|
|
aKey,
|
|
|
|
&aDescriptor,
|
2017-08-03 23:38:33 +03:00
|
|
|
&aBytes.inner,
|
|
|
|
aDirtyRect);
|
2017-07-28 15:08:11 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2018-01-29 16:33:39 +03:00
|
|
|
TransactionBuilder::UpdateExternalImage(ImageKey aKey,
|
|
|
|
const ImageDescriptor& aDescriptor,
|
|
|
|
ExternalImageId aExtID,
|
|
|
|
wr::WrExternalImageBufferType aBufferType,
|
|
|
|
uint8_t aChannelIndex)
|
2017-07-28 15:08:11 +03:00
|
|
|
{
|
2018-05-26 18:09:21 +03:00
|
|
|
wr_resource_updates_update_external_image(mTxn,
|
2017-09-04 14:59:12 +03:00
|
|
|
aKey,
|
|
|
|
&aDescriptor,
|
|
|
|
aExtID,
|
|
|
|
aBufferType,
|
|
|
|
aChannelIndex);
|
2017-07-28 15:08:11 +03:00
|
|
|
}
|
|
|
|
|
2018-07-12 18:43:09 +03:00
|
|
|
void
|
|
|
|
TransactionBuilder::UpdateExternalImageWithDirtyRect(ImageKey aKey,
|
|
|
|
const ImageDescriptor& aDescriptor,
|
|
|
|
ExternalImageId aExtID,
|
|
|
|
wr::WrExternalImageBufferType aBufferType,
|
|
|
|
const wr::DeviceUintRect& aDirtyRect,
|
|
|
|
uint8_t aChannelIndex)
|
|
|
|
{
|
|
|
|
wr_resource_updates_update_external_image_with_dirty_rect(mTxn,
|
|
|
|
aKey,
|
|
|
|
&aDescriptor,
|
|
|
|
aExtID,
|
|
|
|
aBufferType,
|
|
|
|
aChannelIndex,
|
|
|
|
aDirtyRect);
|
|
|
|
}
|
|
|
|
|
2018-07-19 23:33:05 +03:00
|
|
|
void TransactionBuilder::SetImageVisibleArea(ImageKey aKey, const wr::NormalizedRect& aArea)
|
|
|
|
{
|
|
|
|
wr_resource_updates_set_image_visible_area(mTxn, aKey, &aArea);
|
|
|
|
}
|
|
|
|
|
2017-01-16 17:22:47 +03:00
|
|
|
void
|
2018-01-29 16:33:39 +03:00
|
|
|
TransactionBuilder::DeleteImage(ImageKey aKey)
|
2017-01-16 17:22:47 +03:00
|
|
|
{
|
2018-05-26 18:09:21 +03:00
|
|
|
wr_resource_updates_delete_image(mTxn, aKey);
|
2017-01-16 17:22:47 +03:00
|
|
|
}
|
|
|
|
|
2017-02-22 21:19:57 +03:00
|
|
|
void
|
2018-01-29 16:33:39 +03:00
|
|
|
TransactionBuilder::AddRawFont(wr::FontKey aKey, wr::Vec<uint8_t>& aBytes, uint32_t aIndex)
|
2017-01-16 17:22:47 +03:00
|
|
|
{
|
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
|
|
|
}
|
|
|
|
|
2017-11-07 04:19:46 +03:00
|
|
|
void
|
2018-01-29 16:33:39 +03:00
|
|
|
TransactionBuilder::AddFontDescriptor(wr::FontKey aKey, wr::Vec<uint8_t>& aBytes, uint32_t aIndex)
|
2017-11-07 04:19:46 +03:00
|
|
|
{
|
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
|
|
|
}
|
|
|
|
|
2017-01-16 17:22:47 +03:00
|
|
|
void
|
2018-01-29 16:33:39 +03:00
|
|
|
TransactionBuilder::DeleteFont(wr::FontKey aKey)
|
2017-01-16 17:22:47 +03:00
|
|
|
{
|
2018-05-26 18:09:21 +03:00
|
|
|
wr_resource_updates_delete_font(mTxn, aKey);
|
2017-01-16 17:22:47 +03:00
|
|
|
}
|
|
|
|
|
2017-08-30 20:45:11 +03:00
|
|
|
void
|
2018-01-29 16:33:39 +03:00
|
|
|
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
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2018-01-29 16:33:39 +03:00
|
|
|
TransactionBuilder::DeleteFontInstance(wr::FontInstanceKey aKey)
|
2017-08-30 20:45:11 +03:00
|
|
|
{
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
~FrameStartTime()
|
|
|
|
{
|
|
|
|
MOZ_COUNT_DTOR(FrameStartTime);
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void Run(RenderThread& aRenderThread, WindowId aWindowId) override
|
|
|
|
{
|
|
|
|
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-17 22:46:31 +03:00
|
|
|
void
|
2017-01-28 00:08:17 +03:00
|
|
|
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,
|
|
|
|
size_t aCapacity)
|
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
|
|
|
: mActiveFixedPosTracker(nullptr)
|
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
|
|
|
|
|
|
|
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-05-15 22:13:31 +03:00
|
|
|
void
|
2017-07-19 01:32:46 +03:00
|
|
|
DisplayListBuilder::Finalize(wr::LayoutSize& aOutContentSize,
|
2017-05-15 22:13:31 +03:00
|
|
|
BuiltDisplayList& aOutDisplayList)
|
2017-03-01 17:10:53 +03:00
|
|
|
{
|
2017-03-03 18:45:29 +03:00
|
|
|
wr_api_finalize_builder(mWrState,
|
2017-05-15 22:13:31 +03:00
|
|
|
&aOutContentSize,
|
|
|
|
&aOutDisplayList.dl_desc,
|
|
|
|
&aOutDisplayList.dl.inner);
|
2017-03-01 17:10:53 +03:00
|
|
|
}
|
|
|
|
|
2018-05-08 16:16:26 +03:00
|
|
|
Maybe<wr::WrClipId>
|
2017-07-19 01:32:46 +03:00
|
|
|
DisplayListBuilder::PushStackingContext(const wr::LayoutRect& aBounds,
|
2018-04-11 20:00:49 +03:00
|
|
|
const wr::WrClipId* aClipNodeId,
|
2017-11-15 11:09:21 +03:00
|
|
|
const WrAnimationProperty* aAnimation,
|
2017-03-29 12:23:08 +03:00
|
|
|
const float* aOpacity,
|
|
|
|
const gfx::Matrix4x4* aTransform,
|
2017-07-19 10:28:58 +03:00
|
|
|
wr::TransformStyle aTransformStyle,
|
2017-08-14 12:31:55 +03:00
|
|
|
const gfx::Matrix4x4* aPerspective,
|
2017-07-19 10:28:58 +03:00
|
|
|
const wr::MixBlendMode& aMixBlendMode,
|
2017-09-21 09:41:38 +03:00
|
|
|
const nsTArray<wr::WrFilterOp>& aFilters,
|
2018-05-04 03:38:37 +03:00
|
|
|
bool aIsBackfaceVisible,
|
|
|
|
const wr::GlyphRasterSpace& aRasterSpace)
|
2017-03-29 12:23:08 +03:00
|
|
|
{
|
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;
|
2017-03-29 12:23:08 +03:00
|
|
|
if (aTransform) {
|
2017-07-19 01:32:46 +03:00
|
|
|
matrix = ToLayoutTransform(*aTransform);
|
2017-03-29 12:23:08 +03:00
|
|
|
}
|
2017-07-19 01:32:46 +03:00
|
|
|
const wr::LayoutTransform* maybeTransform = aTransform ? &matrix : nullptr;
|
2017-08-14 12:31:55 +03:00
|
|
|
wr::LayoutTransform perspective;
|
|
|
|
if (aPerspective) {
|
|
|
|
perspective = ToLayoutTransform(*aPerspective);
|
|
|
|
}
|
2018-05-04 03:38:37 +03:00
|
|
|
|
2017-08-14 12:31:55 +03:00
|
|
|
const wr::LayoutTransform* maybePerspective = aPerspective ? &perspective : nullptr;
|
2018-04-11 20:00:49 +03:00
|
|
|
const size_t* maybeClipNodeId = aClipNodeId ? &aClipNodeId->id : nullptr;
|
2017-08-28 21:20:25 +03:00
|
|
|
WRDL_LOG("PushStackingContext b=%s t=%s\n", mWrState, Stringify(aBounds).c_str(),
|
2017-05-29 18:40:49 +03:00
|
|
|
aTransform ? Stringify(*aTransform).c_str() : "none");
|
2018-05-08 16:16:26 +03:00
|
|
|
|
|
|
|
bool outIsReferenceFrame = false;
|
|
|
|
uintptr_t outReferenceFrameId = 0;
|
2018-05-04 03:38:37 +03:00
|
|
|
wr_dp_push_stacking_context(mWrState, aBounds, maybeClipNodeId, aAnimation,
|
|
|
|
aOpacity, maybeTransform, aTransformStyle,
|
|
|
|
maybePerspective, aMixBlendMode,
|
|
|
|
aFilters.Elements(), aFilters.Length(),
|
2018-05-08 16:16:26 +03:00
|
|
|
aIsBackfaceVisible, aRasterSpace,
|
|
|
|
&outIsReferenceFrame, &outReferenceFrameId);
|
|
|
|
return outIsReferenceFrame ? Some(wr::WrClipId { outReferenceFrameId }) : Nothing();
|
2017-03-29 12:23:08 +03:00
|
|
|
}
|
|
|
|
|
2017-01-13 13:25:07 +03:00
|
|
|
void
|
2018-05-16 17:47:08 +03:00
|
|
|
DisplayListBuilder::PopStackingContext(bool aIsReferenceFrame)
|
2017-01-13 13:25:07 +03:00
|
|
|
{
|
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(const Maybe<wr::WrClipChainId>& aParent,
|
|
|
|
const nsTArray<wr::WrClipId>& aClips)
|
|
|
|
{
|
|
|
|
nsTArray<size_t> clipIds;
|
|
|
|
for (wr::WrClipId id : aClips) {
|
|
|
|
clipIds.AppendElement(id.id);
|
|
|
|
}
|
|
|
|
uint64_t clipchainId = wr_dp_define_clipchain(mWrState,
|
|
|
|
aParent ? &(aParent->id) : nullptr,
|
|
|
|
clipIds.Elements(), clipIds.Length());
|
|
|
|
WRDL_LOG("DefineClipChain id=%" PRIu64 " p=%s clips=%zu\n", mWrState,
|
|
|
|
clipchainId,
|
|
|
|
aParent ? Stringify(aParent->id).c_str() : "(nil)",
|
|
|
|
clipIds.Length());
|
|
|
|
return wr::WrClipChainId{ clipchainId };
|
|
|
|
}
|
|
|
|
|
2017-08-08 22:43:17 +03:00
|
|
|
wr::WrClipId
|
2018-05-08 16:08:39 +03:00
|
|
|
DisplayListBuilder::DefineClip(const Maybe<wr::WrClipId>& aParentId,
|
2017-10-24 22:45:57 +03:00
|
|
|
const wr::LayoutRect& aClipRect,
|
2017-10-04 00:51:49 +03:00
|
|
|
const nsTArray<wr::ComplexClipRegion>* aComplex,
|
2017-08-08 22:43:17 +03:00
|
|
|
const wr::WrImageMask* aMask)
|
|
|
|
{
|
2018-03-02 00:49:54 +03:00
|
|
|
size_t clip_id = wr_dp_define_clip(mWrState,
|
2018-05-08 16:08:39 +03:00
|
|
|
aParentId ? &(aParentId->id) : nullptr,
|
2017-10-24 22:45:57 +03:00
|
|
|
aClipRect,
|
2017-08-08 22:43:17 +03:00
|
|
|
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,
|
|
|
|
clip_id, aParentId ? Stringify(aParentId->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);
|
|
|
|
return wr::WrClipId { clip_id };
|
|
|
|
}
|
|
|
|
|
2017-04-18 18:09:39 +03:00
|
|
|
void
|
2018-05-08 16:08:39 +03:00
|
|
|
DisplayListBuilder::PushClip(const wr::WrClipId& aClipId)
|
2017-04-18 18:09:39 +03:00
|
|
|
{
|
2018-03-02 00:49:54 +03:00
|
|
|
WRDL_LOG("PushClip id=%zu\n", mWrState, aClipId.id);
|
2018-05-08 16:08:39 +03:00
|
|
|
wr_dp_push_clip(mWrState, aClipId.id);
|
2017-04-18 18:09:39 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2018-05-08 16:08:39 +03:00
|
|
|
DisplayListBuilder::PopClip()
|
2017-04-18 18:09:39 +03:00
|
|
|
{
|
2017-10-24 22:45:58 +03:00
|
|
|
WRDL_LOG("PopClip\n", mWrState);
|
2017-10-25 22:05:20 +03:00
|
|
|
wr_dp_pop_clip(mWrState);
|
|
|
|
}
|
|
|
|
|
2018-05-08 16:08:39 +03:00
|
|
|
wr::WrClipId
|
2017-09-21 17:11:39 +03:00
|
|
|
DisplayListBuilder::DefineStickyFrame(const wr::LayoutRect& aContentRect,
|
2017-10-31 16:17:22 +03:00
|
|
|
const float* aTopMargin,
|
|
|
|
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)
|
2017-10-31 16:17:22 +03:00
|
|
|
{
|
2018-03-02 00:49:54 +03:00
|
|
|
size_t id = wr_dp_define_sticky_frame(mWrState, aContentRect, aTopMargin,
|
2017-11-07 18:16:48 +03:00
|
|
|
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",
|
2017-10-31 16:17:22 +03:00
|
|
|
mWrState, id,
|
2017-09-21 17:11:39 +03:00
|
|
|
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());
|
2018-05-08 16:08:39 +03:00
|
|
|
return wr::WrClipId { id };
|
2017-09-21 17:11:39 +03:00
|
|
|
}
|
|
|
|
|
2018-05-08 16:08:39 +03:00
|
|
|
Maybe<wr::WrClipId>
|
2018-01-22 21:29:06 +03:00
|
|
|
DisplayListBuilder::GetScrollIdForDefinedScrollLayer(layers::FrameMetrics::ViewID aViewId) const
|
2017-08-30 21:51:19 +03:00
|
|
|
{
|
2018-01-22 21:29:06 +03:00
|
|
|
if (aViewId == layers::FrameMetrics::NULL_SCROLL_ID) {
|
2018-05-08 16:08:39 +03:00
|
|
|
return Some(wr::WrClipId::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
|
|
|
}
|
|
|
|
|
2018-05-08 16:08:39 +03:00
|
|
|
wr::WrClipId
|
2018-01-22 21:29:06 +03:00
|
|
|
DisplayListBuilder::DefineScrollLayer(const layers::FrameMetrics::ViewID& aViewId,
|
2018-05-08 16:08:39 +03:00
|
|
|
const Maybe<wr::WrClipId>& aParentId,
|
2017-08-30 21:51:19 +03:00
|
|
|
const wr::LayoutRect& aContentRect,
|
|
|
|
const wr::LayoutRect& aClipRect)
|
2017-02-14 21:34:15 +03:00
|
|
|
{
|
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.
|
2018-03-02 00:49:54 +03:00
|
|
|
size_t numericScrollId = wr_dp_define_scroll_layer(
|
2018-01-22 21:29:06 +03:00
|
|
|
mWrState,
|
|
|
|
aViewId,
|
2018-05-08 16:08:39 +03:00
|
|
|
aParentId ? &(aParentId->id) : nullptr,
|
2018-01-22 21:29:06 +03:00
|
|
|
aContentRect,
|
|
|
|
aClipRect);
|
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,
|
|
|
|
aViewId, numericScrollId,
|
|
|
|
aParentId ? Stringify(aParentId->id).c_str() : "(nil)",
|
|
|
|
Stringify(aContentRect).c_str(), Stringify(aClipRect).c_str());
|
2017-02-14 21:34:15 +03:00
|
|
|
|
2018-05-08 16:08:39 +03:00
|
|
|
auto clipId = wr::WrClipId { numericScrollId };
|
|
|
|
mScrollIds[aViewId] = clipId;
|
|
|
|
return clipId;
|
2017-02-14 21:34:15 +03:00
|
|
|
}
|
|
|
|
|
2017-06-08 18:34:01 +03:00
|
|
|
void
|
2018-09-14 17:42:20 +03:00
|
|
|
DisplayListBuilder::PushClipAndScrollInfo(const wr::WrClipId* aScrollId,
|
|
|
|
const wr::WrClipChainId* aClipChainId,
|
|
|
|
const Maybe<wr::LayoutRect>& aClipChainLeaf)
|
2017-06-08 18:34:01 +03:00
|
|
|
{
|
2018-09-14 17:42:20 +03:00
|
|
|
if (aScrollId) {
|
|
|
|
WRDL_LOG("PushClipAndScroll s=%zu c=%s\n", mWrState, aScrollId->id,
|
|
|
|
aClipChainId ? Stringify(aClipChainId->id).c_str() : "none");
|
|
|
|
wr_dp_push_clip_and_scroll_info(mWrState, aScrollId->id,
|
|
|
|
aClipChainId ? &(aClipChainId->id) : nullptr);
|
|
|
|
}
|
|
|
|
mClipChainLeaf = aClipChainLeaf;
|
2017-06-08 18:34:01 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2018-09-14 17:42:20 +03:00
|
|
|
DisplayListBuilder::PopClipAndScrollInfo(const wr::WrClipId* aScrollId)
|
2017-06-08 18:34:01 +03:00
|
|
|
{
|
2018-09-14 17:42:20 +03:00
|
|
|
if (aScrollId) {
|
|
|
|
WRDL_LOG("PopClipAndScroll\n", mWrState);
|
|
|
|
wr_dp_pop_clip_and_scroll_info(mWrState);
|
|
|
|
}
|
|
|
|
mClipChainLeaf.reset();
|
2017-06-08 18:34:01 +03:00
|
|
|
}
|
|
|
|
|
2017-01-13 13:25:07 +03:00
|
|
|
void
|
2017-07-19 01:32:46 +03:00
|
|
|
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)
|
2017-01-13 13:25:07 +03:00
|
|
|
{
|
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,
|
2017-05-29 18:40:49 +03:00
|
|
|
Stringify(aBounds).c_str(),
|
2018-09-14 17:42:20 +03:00
|
|
|
Stringify(clip).c_str(),
|
2017-05-29 18:40:49 +03:00
|
|
|
Stringify(aColor).c_str());
|
2018-09-14 17:42:20 +03:00
|
|
|
wr_dp_push_rect(mWrState, aBounds, clip,
|
|
|
|
aIsBackfaceVisible, aColor);
|
2017-01-13 13:25:07 +03:00
|
|
|
}
|
|
|
|
|
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());
|
|
|
|
wr_dp_push_clear_rect(mWrState, aBounds, clip);
|
2017-10-31 18:31:00 +03:00
|
|
|
}
|
|
|
|
|
2017-02-17 03:51:32 +03:00
|
|
|
void
|
2017-07-19 01:32:46 +03:00
|
|
|
DisplayListBuilder::PushLinearGradient(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::LayoutPoint& aStartPoint,
|
|
|
|
const wr::LayoutPoint& aEndPoint,
|
2017-07-19 08:47:07 +03:00
|
|
|
const nsTArray<wr::GradientStop>& aStops,
|
|
|
|
wr::ExtendMode aExtendMode,
|
2017-07-19 01:32:46 +03:00
|
|
|
const wr::LayoutSize aTileSize,
|
|
|
|
const wr::LayoutSize aTileSpacing)
|
2017-02-17 03:51:32 +03:00
|
|
|
{
|
|
|
|
wr_dp_push_linear_gradient(mWrState,
|
2018-09-14 17:42:20 +03:00
|
|
|
aBounds, MergeClipLeaf(aClip),
|
|
|
|
aIsBackfaceVisible,
|
2017-02-17 03:51:32 +03:00
|
|
|
aStartPoint, aEndPoint,
|
|
|
|
aStops.Elements(), aStops.Length(),
|
2017-04-12 22:20:52 +03:00
|
|
|
aExtendMode,
|
|
|
|
aTileSize, aTileSpacing);
|
2017-02-17 03:51:32 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2017-07-19 01:32:46 +03:00
|
|
|
DisplayListBuilder::PushRadialGradient(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::LayoutPoint& aCenter,
|
|
|
|
const wr::LayoutSize& aRadius,
|
2017-07-19 08:47:07 +03:00
|
|
|
const nsTArray<wr::GradientStop>& aStops,
|
|
|
|
wr::ExtendMode aExtendMode,
|
2017-07-19 01:32:46 +03:00
|
|
|
const wr::LayoutSize aTileSize,
|
|
|
|
const wr::LayoutSize aTileSpacing)
|
2017-02-17 03:51:32 +03:00
|
|
|
{
|
|
|
|
wr_dp_push_radial_gradient(mWrState,
|
2018-09-14 17:42:20 +03:00
|
|
|
aBounds, MergeClipLeaf(aClip),
|
|
|
|
aIsBackfaceVisible,
|
2017-04-01 02:18:44 +03:00
|
|
|
aCenter, aRadius,
|
2017-02-17 03:51:32 +03:00
|
|
|
aStops.Elements(), aStops.Length(),
|
2017-04-12 22:20:52 +03:00
|
|
|
aExtendMode,
|
|
|
|
aTileSize, aTileSpacing);
|
2017-02-17 03:51:32 +03:00
|
|
|
}
|
|
|
|
|
2017-01-13 13:25:07 +03:00
|
|
|
void
|
2017-07-19 01:32:46 +03:00
|
|
|
DisplayListBuilder::PushImage(const wr::LayoutRect& aBounds,
|
|
|
|
const wr::LayoutRect& aClip,
|
2017-09-21 09:41:38 +03:00
|
|
|
bool aIsBackfaceVisible,
|
2017-02-14 21:34:15 +03:00
|
|
|
wr::ImageRendering aFilter,
|
2018-01-17 20:55:40 +03:00
|
|
|
wr::ImageKey aImage,
|
2018-08-21 19:36:48 +03:00
|
|
|
bool aPremultipliedAlpha,
|
|
|
|
const wr::ColorF& aColor)
|
2017-01-13 13:25:07 +03:00
|
|
|
{
|
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
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2017-07-19 01:32:46 +03:00
|
|
|
DisplayListBuilder::PushImage(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::LayoutSize& aStretchSize,
|
|
|
|
const wr::LayoutSize& aTileSpacing,
|
2017-04-07 09:53:16 +03:00
|
|
|
wr::ImageRendering aFilter,
|
2018-01-17 20:55:40 +03:00
|
|
|
wr::ImageKey aImage,
|
2018-08-21 19:36:48 +03:00
|
|
|
bool aPremultipliedAlpha,
|
|
|
|
const wr::ColorF& aColor)
|
2017-04-07 09:53:16 +03:00
|
|
|
{
|
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(),
|
2018-09-14 17:42:20 +03:00
|
|
|
Stringify(clip).c_str(), Stringify(aStretchSize).c_str(),
|
2017-06-26 14:49:52 +03:00
|
|
|
Stringify(aTileSpacing).c_str());
|
2018-09-14 17:42:20 +03:00
|
|
|
wr_dp_push_image(mWrState, aBounds, clip, aIsBackfaceVisible,
|
|
|
|
aStretchSize, aTileSpacing, aFilter, aImage,
|
|
|
|
aPremultipliedAlpha, aColor);
|
2017-01-13 13:25:07 +03:00
|
|
|
}
|
|
|
|
|
2017-04-29 00:00:57 +03:00
|
|
|
void
|
2017-07-19 01:32:46 +03:00
|
|
|
DisplayListBuilder::PushYCbCrPlanarImage(const wr::LayoutRect& aBounds,
|
|
|
|
const wr::LayoutRect& aClip,
|
2017-09-21 09:41:38 +03:00
|
|
|
bool aIsBackfaceVisible,
|
2017-04-29 00:00:57 +03:00
|
|
|
wr::ImageKey aImageChannel0,
|
|
|
|
wr::ImageKey aImageChannel1,
|
|
|
|
wr::ImageKey aImageChannel2,
|
2017-06-28 02:20:36 +03:00
|
|
|
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,
|
2018-09-14 17:42:20 +03:00
|
|
|
MergeClipLeaf(aClip),
|
2017-09-21 09:41:38 +03:00
|
|
|
aIsBackfaceVisible,
|
2017-04-29 00:00:57 +03:00
|
|
|
aImageChannel0,
|
|
|
|
aImageChannel1,
|
|
|
|
aImageChannel2,
|
2017-06-01 15:57:10 +03:00
|
|
|
aColorSpace,
|
|
|
|
aRendering);
|
2017-04-29 00:00:57 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2017-07-19 01:32:46 +03:00
|
|
|
DisplayListBuilder::PushNV12Image(const wr::LayoutRect& aBounds,
|
|
|
|
const wr::LayoutRect& aClip,
|
2017-09-21 09:41:38 +03:00
|
|
|
bool aIsBackfaceVisible,
|
2017-04-29 00:00:57 +03:00
|
|
|
wr::ImageKey aImageChannel0,
|
|
|
|
wr::ImageKey aImageChannel1,
|
2017-06-28 02:20:36 +03:00
|
|
|
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_NV12_image(mWrState,
|
|
|
|
aBounds,
|
2018-09-14 17:42:20 +03:00
|
|
|
MergeClipLeaf(aClip),
|
2017-09-21 09:41:38 +03:00
|
|
|
aIsBackfaceVisible,
|
2017-04-29 00:00:57 +03:00
|
|
|
aImageChannel0,
|
|
|
|
aImageChannel1,
|
2017-06-01 15:57:10 +03:00
|
|
|
aColorSpace,
|
|
|
|
aRendering);
|
2017-04-29 00:00:57 +03:00
|
|
|
}
|
|
|
|
|
2017-05-18 17:59:07 +03:00
|
|
|
void
|
2017-07-19 01:32:46 +03:00
|
|
|
DisplayListBuilder::PushYCbCrInterleavedImage(const wr::LayoutRect& aBounds,
|
|
|
|
const wr::LayoutRect& aClip,
|
2017-09-21 09:41:38 +03:00
|
|
|
bool aIsBackfaceVisible,
|
2017-05-18 17:59:07 +03:00
|
|
|
wr::ImageKey aImageChannel0,
|
2017-06-28 02:20:36 +03:00
|
|
|
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,
|
2018-09-14 17:42:20 +03:00
|
|
|
MergeClipLeaf(aClip),
|
2017-09-21 09:41:38 +03:00
|
|
|
aIsBackfaceVisible,
|
2017-05-18 17:59:07 +03:00
|
|
|
aImageChannel0,
|
2017-06-01 15:57:10 +03:00
|
|
|
aColorSpace,
|
|
|
|
aRendering);
|
2017-05-18 17:59:07 +03:00
|
|
|
}
|
|
|
|
|
2017-01-13 13:25:07 +03:00
|
|
|
void
|
2017-07-19 01:32:46 +03:00
|
|
|
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)
|
2017-01-13 13:25:07 +03:00
|
|
|
{
|
2018-09-14 17:42:20 +03:00
|
|
|
wr_dp_push_iframe(mWrState, aBounds, MergeClipLeaf(aBounds),
|
|
|
|
aIsBackfaceVisible, aPipeline, aIgnoreMissingPipeline);
|
2017-01-13 13:25:07 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2017-07-19 01:32:46 +03:00
|
|
|
DisplayListBuilder::PushBorder(const wr::LayoutRect& aBounds,
|
|
|
|
const wr::LayoutRect& aClip,
|
2017-09-21 09:41:38 +03:00
|
|
|
bool aIsBackfaceVisible,
|
2017-07-19 08:56:20 +03:00
|
|
|
const wr::BorderWidths& aWidths,
|
|
|
|
const Range<const wr::BorderSide>& aSides,
|
|
|
|
const wr::BorderRadius& aRadius)
|
2017-01-13 13:25:07 +03:00
|
|
|
{
|
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,
|
2017-07-01 02:22:25 +03:00
|
|
|
aWidths, aSides[0], aSides[1], aSides[2], aSides[3], aRadius);
|
2017-03-13 06:46:03 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2017-07-19 01:32:46 +03:00
|
|
|
DisplayListBuilder::PushBorderImage(const wr::LayoutRect& aBounds,
|
|
|
|
const wr::LayoutRect& aClip,
|
2017-09-21 09:41:38 +03:00
|
|
|
bool aIsBackfaceVisible,
|
2017-07-19 08:56:20 +03:00
|
|
|
const wr::BorderWidths& aWidths,
|
2017-03-13 06:46:03 +03:00
|
|
|
wr::ImageKey aImage,
|
2018-05-08 17:36:23 +03:00
|
|
|
const uint32_t aWidth,
|
|
|
|
const uint32_t aHeight,
|
|
|
|
const wr::SideOffsets2D<uint32_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)
|
2017-03-13 06:46:03 +03:00
|
|
|
{
|
2018-09-14 17:42:20 +03:00
|
|
|
wr_dp_push_border_image(mWrState, aBounds, MergeClipLeaf(aClip),
|
|
|
|
aIsBackfaceVisible, aWidths, aImage, aWidth, aHeight,
|
|
|
|
aSlice, aOutset, aRepeatHorizontal, aRepeatVertical);
|
2017-01-13 13:25:07 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2017-07-19 01:32:46 +03:00
|
|
|
DisplayListBuilder::PushBorderGradient(const wr::LayoutRect& aBounds,
|
|
|
|
const wr::LayoutRect& aClip,
|
2017-09-21 09:41:38 +03:00
|
|
|
bool aIsBackfaceVisible,
|
2017-07-19 08:56:20 +03:00
|
|
|
const wr::BorderWidths& aWidths,
|
2018-06-14 01:40:13 +03:00
|
|
|
const uint32_t aWidth,
|
|
|
|
const uint32_t aHeight,
|
|
|
|
const wr::SideOffsets2D<uint32_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)
|
2017-04-10 12:27:30 +03:00
|
|
|
{
|
2018-09-14 17:42:20 +03:00
|
|
|
wr_dp_push_border_gradient(mWrState, aBounds, MergeClipLeaf(aClip),
|
|
|
|
aIsBackfaceVisible, aWidths, aWidth, aHeight,
|
|
|
|
aSlice, aStartPoint, aEndPoint,
|
2017-04-10 12:27:30 +03:00
|
|
|
aStops.Elements(), aStops.Length(),
|
|
|
|
aExtendMode, aOutset);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2017-07-19 01:32:46 +03:00
|
|
|
DisplayListBuilder::PushBorderRadialGradient(const wr::LayoutRect& aBounds,
|
|
|
|
const wr::LayoutRect& aClip,
|
2017-09-21 09:41:38 +03:00
|
|
|
bool aIsBackfaceVisible,
|
2017-07-19 08:56:20 +03:00
|
|
|
const wr::BorderWidths& 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)
|
2017-04-10 12:27:30 +03:00
|
|
|
{
|
|
|
|
wr_dp_push_border_radial_gradient(
|
2018-09-14 17:42:20 +03:00
|
|
|
mWrState, aBounds, MergeClipLeaf(aClip), aIsBackfaceVisible,
|
|
|
|
aWidths, aCenter, aRadius, aStops.Elements(), aStops.Length(),
|
2017-04-10 12:27:30 +03:00
|
|
|
aExtendMode, aOutset);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2017-07-19 01:32:46 +03:00
|
|
|
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)
|
2017-01-13 13:25:07 +03:00
|
|
|
{
|
2018-09-14 17:42:20 +03:00
|
|
|
wr_dp_push_text(mWrState, aBounds, MergeClipLeaf(aClip),
|
|
|
|
aIsBackfaceVisible,
|
2017-10-04 20:49:51 +03:00
|
|
|
aColor,
|
2017-02-14 21:34:15 +03:00
|
|
|
aFontKey,
|
2017-01-13 13:25:07 +03:00
|
|
|
&aGlyphBuffer[0], aGlyphBuffer.length(),
|
2017-08-30 20:45:11 +03:00
|
|
|
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);
|
|
|
|
wr_dp_push_line(mWrState, &clip, aIsBackfaceVisible,
|
|
|
|
&aLine.bounds, 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
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2017-10-04 21:54:37 +03:00
|
|
|
DisplayListBuilder::PushShadow(const wr::LayoutRect& aRect,
|
|
|
|
const wr::LayoutRect& aClip,
|
|
|
|
bool aIsBackfaceVisible,
|
|
|
|
const wr::Shadow& aShadow)
|
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
|
|
|
{
|
2018-09-14 17:42:20 +03:00
|
|
|
wr_dp_push_shadow(mWrState, aRect, MergeClipLeaf(aClip),
|
|
|
|
aIsBackfaceVisible, aShadow);
|
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
|
2017-10-13 19:58:32 +03:00
|
|
|
DisplayListBuilder::PopAllShadows()
|
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-13 19:58:32 +03:00
|
|
|
wr_dp_pop_all_shadows(mWrState);
|
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-02-16 21:23:22 +03:00
|
|
|
void
|
2017-07-19 01:32:46 +03:00
|
|
|
DisplayListBuilder::PushBoxShadow(const wr::LayoutRect& aRect,
|
|
|
|
const wr::LayoutRect& aClip,
|
2017-09-21 09:41:38 +03:00
|
|
|
bool aIsBackfaceVisible,
|
2017-07-19 01:32:46 +03:00
|
|
|
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)
|
2017-02-16 21:23:22 +03:00
|
|
|
{
|
2018-09-14 17:42:20 +03:00
|
|
|
wr_dp_push_box_shadow(mWrState, aRect, MergeClipLeaf(aClip),
|
|
|
|
aIsBackfaceVisible, aBoxBounds, aOffset, aColor,
|
2017-02-16 21:23:22 +03:00
|
|
|
aBlurRadius, aSpreadRadius, aBorderRadius,
|
|
|
|
aClipMode);
|
|
|
|
}
|
|
|
|
|
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
|
|
|
Maybe<layers::FrameMetrics::ViewID>
|
|
|
|
DisplayListBuilder::GetContainingFixedPosScrollTarget(const ActiveScrolledRoot* aAsr)
|
|
|
|
{
|
|
|
|
return mActiveFixedPosTracker
|
|
|
|
? mActiveFixedPosTracker->GetScrollTargetForASR(aAsr)
|
|
|
|
: Nothing();
|
|
|
|
}
|
|
|
|
|
2017-11-15 19:39:44 +03:00
|
|
|
void
|
|
|
|
DisplayListBuilder::SetHitTestInfo(const layers::FrameMetrics::ViewID& aScrollId,
|
|
|
|
gfx::CompositorHitTestInfo aHitInfo)
|
|
|
|
{
|
2017-11-23 17:40:00 +03:00
|
|
|
static_assert(sizeof(gfx::CompositorHitTestInfo) == sizeof(uint16_t),
|
|
|
|
"CompositorHitTestInfo should be u16-sized");
|
|
|
|
wr_set_item_tag(mWrState, aScrollId, static_cast<uint16_t>(aHitInfo));
|
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,
|
|
|
|
layers::FrameMetrics::ViewID aScrollId)
|
|
|
|
: mParentTracker(aBuilder.mActiveFixedPosTracker)
|
|
|
|
, mBuilder(aBuilder)
|
|
|
|
, mAsr(aAsr)
|
|
|
|
, mScrollId(aScrollId)
|
|
|
|
{
|
|
|
|
aBuilder.mActiveFixedPosTracker = this;
|
|
|
|
}
|
|
|
|
|
|
|
|
DisplayListBuilder::FixedPosScrollTargetTracker::~FixedPosScrollTargetTracker()
|
|
|
|
{
|
|
|
|
mBuilder.mActiveFixedPosTracker = mParentTracker;
|
|
|
|
}
|
|
|
|
|
|
|
|
Maybe<layers::FrameMetrics::ViewID>
|
|
|
|
DisplayListBuilder::FixedPosScrollTargetTracker::GetScrollTargetForASR(const ActiveScrolledRoot* aAsr)
|
|
|
|
{
|
|
|
|
return aAsr == mAsr ? Some(mScrollId) : Nothing();
|
|
|
|
}
|
|
|
|
|
2017-01-25 00:06:17 +03:00
|
|
|
} // namespace wr
|
|
|
|
} // namespace mozilla
|