Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/gfx/webrender_bindings/WebRenderAPI.cpp
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3
/* This Source Code Form is subject to the terms of the Mozilla Public
4
 * License, v. 2.0. If a copy of the MPL was not distributed with this
5
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#include "WebRenderAPI.h"
8
9
#include "gfxPrefs.h"
10
#include "LayersLogging.h"
11
#include "mozilla/webrender/RendererOGL.h"
12
#include "mozilla/gfx/gfxVars.h"
13
#include "mozilla/layers/CompositorThread.h"
14
#include "mozilla/webrender/RenderCompositor.h"
15
#include "mozilla/widget/CompositorWidget.h"
16
#include "mozilla/layers/SynchronousTask.h"
17
18
#define WRDL_LOG(...)
19
//#define WRDL_LOG(...) printf_stderr("WRDL(%p): " __VA_ARGS__)
20
//#define WRDL_LOG(...) if (XRE_IsContentProcess()) printf_stderr("WRDL(%p): " __VA_ARGS__)
21
22
namespace mozilla {
23
namespace wr {
24
25
using layers::Stringify;
26
27
MOZ_DEFINE_MALLOC_SIZE_OF(WebRenderMallocSizeOf)
28
29
class NewRenderer : public RendererEvent
30
{
31
public:
32
  NewRenderer(wr::DocumentHandle** aDocHandle,
33
              layers::CompositorBridgeParent* aBridge,
34
              uint32_t* aMaxTextureSize,
35
              bool* aUseANGLE,
36
              bool* aUseDComp,
37
              RefPtr<widget::CompositorWidget>&& aWidget,
38
              layers::SynchronousTask* aTask,
39
              LayoutDeviceIntSize aSize,
40
              layers::SyncHandle* aHandle)
41
    : mDocHandle(aDocHandle)
42
    , mMaxTextureSize(aMaxTextureSize)
43
    , mUseANGLE(aUseANGLE)
44
    , mUseDComp(aUseDComp)
45
    , mBridge(aBridge)
46
    , mCompositorWidget(std::move(aWidget))
47
    , mTask(aTask)
48
    , mSize(aSize)
49
    , mSyncHandle(aHandle)
50
0
  {
51
0
    MOZ_COUNT_CTOR(NewRenderer);
52
0
  }
53
54
  ~NewRenderer()
55
0
  {
56
0
    MOZ_COUNT_DTOR(NewRenderer);
57
0
  }
58
59
  virtual void Run(RenderThread& aRenderThread, WindowId aWindowId) override
60
0
  {
61
0
    layers::AutoCompleteTask complete(mTask);
62
0
63
0
    UniquePtr<RenderCompositor> compositor = RenderCompositor::Create(std::move(mCompositorWidget));
64
0
    if (!compositor) {
65
0
      // RenderCompositor::Create puts a message into gfxCriticalNote if it is nullptr
66
0
      return;
67
0
    }
68
0
69
0
    *mUseANGLE = compositor->UseANGLE();
70
0
    *mUseDComp = compositor->UseDComp();
71
0
72
0
    bool supportLowPriorityTransactions = true; // TODO only for main windows.
73
0
    wr::Renderer* wrRenderer = nullptr;
74
0
    if (!wr_window_new(aWindowId, mSize.width, mSize.height, supportLowPriorityTransactions,
75
0
                       compositor->gl(),
76
0
                       aRenderThread.ThreadPool().Raw(),
77
0
                       &WebRenderMallocSizeOf,
78
0
                       mDocHandle, &wrRenderer,
79
0
                       mMaxTextureSize)) {
80
0
      // wr_window_new puts a message into gfxCriticalNote if it returns false
81
0
      return;
82
0
    }
83
0
    MOZ_ASSERT(wrRenderer);
84
0
85
0
    RefPtr<RenderThread> thread = &aRenderThread;
86
0
    auto renderer = MakeUnique<RendererOGL>(std::move(thread),
87
0
                                            std::move(compositor),
88
0
                                            aWindowId,
89
0
                                            wrRenderer,
90
0
                                            mBridge);
91
0
    if (wrRenderer && renderer) {
92
0
      wr::WrExternalImageHandler handler = renderer->GetExternalImageHandler();
93
0
      wr_renderer_set_external_image_handler(wrRenderer, &handler);
94
0
      if (gfx::gfxVars::UseWebRenderProgramBinary()) {
95
0
        wr_renderer_update_program_cache(wrRenderer, aRenderThread.ProgramCache()->Raw());
96
0
      }
97
0
    }
98
0
99
0
    if (renderer) {
100
0
      layers::SyncObjectHost* syncObj = renderer->GetSyncObject();
101
0
      if (syncObj) {
102
0
        *mSyncHandle = syncObj->GetSyncHandle();
103
0
      }
104
0
    }
105
0
106
0
    aRenderThread.AddRenderer(aWindowId, std::move(renderer));
107
0
  }
108
109
private:
110
  wr::DocumentHandle** mDocHandle;
111
  uint32_t* mMaxTextureSize;
112
  bool* mUseANGLE;
113
  bool* mUseDComp;
114
  layers::CompositorBridgeParent* mBridge;
115
  RefPtr<widget::CompositorWidget> mCompositorWidget;
116
  layers::SynchronousTask* mTask;
117
  LayoutDeviceIntSize mSize;
118
  layers::SyncHandle* mSyncHandle;
119
};
120
121
class RemoveRenderer : public RendererEvent
122
{
123
public:
124
  explicit RemoveRenderer(layers::SynchronousTask* aTask)
125
    : mTask(aTask)
126
0
  {
127
0
    MOZ_COUNT_CTOR(RemoveRenderer);
128
0
  }
129
130
  ~RemoveRenderer()
131
0
  {
132
0
    MOZ_COUNT_DTOR(RemoveRenderer);
133
0
  }
134
135
  virtual void Run(RenderThread& aRenderThread, WindowId aWindowId) override
136
0
  {
137
0
    aRenderThread.RemoveRenderer(aWindowId);
138
0
    layers::AutoCompleteTask complete(mTask);
139
0
  }
140
141
private:
142
  layers::SynchronousTask* mTask;
143
};
144
145
146
TransactionBuilder::TransactionBuilder(bool aUseSceneBuilderThread)
147
  : mUseSceneBuilderThread(aUseSceneBuilderThread)
148
0
{
149
0
  mTxn = wr_transaction_new(mUseSceneBuilderThread);
150
0
}
151
152
TransactionBuilder::~TransactionBuilder()
153
0
{
154
0
  wr_transaction_delete(mTxn);
155
0
}
156
157
void
158
TransactionBuilder::SetLowPriority(bool aIsLowPriority)
159
0
{
160
0
  wr_transaction_set_low_priority(mTxn, aIsLowPriority);
161
0
}
162
163
void
164
TransactionBuilder::UpdateEpoch(PipelineId aPipelineId, Epoch aEpoch)
165
0
{
166
0
  wr_transaction_update_epoch(mTxn, aPipelineId, aEpoch);
167
0
}
168
169
void
170
TransactionBuilder::SetRootPipeline(PipelineId aPipelineId)
171
0
{
172
0
  wr_transaction_set_root_pipeline(mTxn, aPipelineId);
173
0
}
174
175
void
176
TransactionBuilder::RemovePipeline(PipelineId aPipelineId)
177
0
{
178
0
  wr_transaction_remove_pipeline(mTxn, aPipelineId);
179
0
}
180
181
void
182
TransactionBuilder::SetDisplayList(gfx::Color aBgColor,
183
                                   Epoch aEpoch,
184
                                   mozilla::LayerSize aViewportSize,
185
                                   wr::WrPipelineId pipeline_id,
186
                                   const wr::LayoutSize& content_size,
187
                                   wr::BuiltDisplayListDescriptor dl_descriptor,
188
                                   wr::Vec<uint8_t>& dl_data)
189
0
{
190
0
  wr_transaction_set_display_list(mTxn,
191
0
                                  aEpoch,
192
0
                                  ToColorF(aBgColor),
193
0
                                  aViewportSize.width, aViewportSize.height,
194
0
                                  pipeline_id,
195
0
                                  content_size,
196
0
                                  dl_descriptor,
197
0
                                  &dl_data.inner);
198
0
}
199
200
void
201
TransactionBuilder::ClearDisplayList(Epoch aEpoch, wr::WrPipelineId aPipelineId)
202
0
{
203
0
  wr_transaction_clear_display_list(mTxn, aEpoch, aPipelineId);
204
0
}
205
206
void
207
TransactionBuilder::GenerateFrame()
208
0
{
209
0
  wr_transaction_generate_frame(mTxn);
210
0
}
211
212
void
213
TransactionBuilder::UpdateDynamicProperties(const nsTArray<wr::WrOpacityProperty>& aOpacityArray,
214
                                     const nsTArray<wr::WrTransformProperty>& aTransformArray)
215
0
{
216
0
  wr_transaction_update_dynamic_properties(
217
0
      mTxn,
218
0
      aOpacityArray.IsEmpty() ?  nullptr : aOpacityArray.Elements(),
219
0
      aOpacityArray.Length(),
220
0
      aTransformArray.IsEmpty() ?  nullptr : aTransformArray.Elements(),
221
0
      aTransformArray.Length());
222
0
}
223
224
bool
225
TransactionBuilder::IsEmpty() const
226
0
{
227
0
  return wr_transaction_is_empty(mTxn);
228
0
}
229
230
void
231
TransactionBuilder::SetWindowParameters(const LayoutDeviceIntSize& aWindowSize,
232
                                        const LayoutDeviceIntRect& aDocumentRect)
233
0
{
234
0
  wr::DeviceUintSize wrWindowSize;
235
0
  wrWindowSize.width = aWindowSize.width;
236
0
  wrWindowSize.height = aWindowSize.height;
237
0
  wr::DeviceUintRect wrDocRect;
238
0
  wrDocRect.origin.x = aDocumentRect.x;
239
0
  wrDocRect.origin.y = aDocumentRect.y;
240
0
  wrDocRect.size.width = aDocumentRect.width;
241
0
  wrDocRect.size.height = aDocumentRect.height;
242
0
  wr_transaction_set_window_parameters(mTxn, &wrWindowSize, &wrDocRect);
243
0
}
244
245
void
246
TransactionBuilder::UpdateScrollPosition(const wr::WrPipelineId& aPipelineId,
247
                                         const layers::FrameMetrics::ViewID& aScrollId,
248
                                         const wr::LayoutPoint& aScrollPosition)
249
0
{
250
0
  wr_transaction_scroll_layer(mTxn, aPipelineId, aScrollId, aScrollPosition);
251
0
}
252
253
TransactionWrapper::TransactionWrapper(Transaction* aTxn)
254
  : mTxn(aTxn)
255
0
{
256
0
}
257
258
void
259
TransactionWrapper::AppendTransformProperties(const nsTArray<wr::WrTransformProperty>& aTransformArray)
260
0
{
261
0
  wr_transaction_append_transform_properties(
262
0
      mTxn,
263
0
      aTransformArray.IsEmpty() ? nullptr : aTransformArray.Elements(),
264
0
      aTransformArray.Length());
265
0
}
266
267
void
268
TransactionWrapper::UpdateScrollPosition(const wr::WrPipelineId& aPipelineId,
269
                                         const layers::FrameMetrics::ViewID& aScrollId,
270
                                         const wr::LayoutPoint& aScrollPosition)
271
0
{
272
0
  wr_transaction_scroll_layer(mTxn, aPipelineId, aScrollId, aScrollPosition);
273
0
}
274
275
/*static*/ already_AddRefed<WebRenderAPI>
276
WebRenderAPI::Create(layers::CompositorBridgeParent* aBridge,
277
                     RefPtr<widget::CompositorWidget>&& aWidget,
278
                     const wr::WrWindowId& aWindowId,
279
                     LayoutDeviceIntSize aSize)
280
0
{
281
0
  MOZ_ASSERT(aBridge);
282
0
  MOZ_ASSERT(aWidget);
283
0
  static_assert(sizeof(size_t) == sizeof(uintptr_t),
284
0
      "The FFI bindings assume size_t is the same size as uintptr_t!");
285
0
286
0
  wr::DocumentHandle* docHandle = nullptr;
287
0
  uint32_t maxTextureSize = 0;
288
0
  bool useANGLE = false;
289
0
  bool useDComp = false;
290
0
  layers::SyncHandle syncHandle = 0;
291
0
292
0
  // Dispatch a synchronous task because the DocumentHandle object needs to be created
293
0
  // on the render thread. If need be we could delay waiting on this task until
294
0
  // the next time we need to access the DocumentHandle object.
295
0
  layers::SynchronousTask task("Create Renderer");
296
0
  auto event = MakeUnique<NewRenderer>(&docHandle, aBridge, &maxTextureSize, &useANGLE, &useDComp,
297
0
                                       std::move(aWidget), &task, aSize,
298
0
                                       &syncHandle);
299
0
  RenderThread::Get()->RunEvent(aWindowId, std::move(event));
300
0
301
0
  task.Wait();
302
0
303
0
  if (!docHandle) {
304
0
    return nullptr;
305
0
  }
306
0
307
0
  return RefPtr<WebRenderAPI>(new WebRenderAPI(docHandle, aWindowId, maxTextureSize, useANGLE, useDComp, syncHandle)).forget();
308
0
}
309
310
already_AddRefed<WebRenderAPI>
311
WebRenderAPI::Clone()
312
0
{
313
0
  wr::DocumentHandle* docHandle = nullptr;
314
0
  wr_api_clone(mDocHandle, &docHandle);
315
0
316
0
  RefPtr<WebRenderAPI> renderApi = new WebRenderAPI(docHandle, mId, mMaxTextureSize, mUseANGLE, mUseDComp, mSyncHandle);
317
0
  renderApi->mRootApi = this; // Hold root api
318
0
  renderApi->mRootDocumentApi = this;
319
0
  return renderApi.forget();
320
0
}
321
322
already_AddRefed<WebRenderAPI>
323
WebRenderAPI::CreateDocument(LayoutDeviceIntSize aSize, int8_t aLayerIndex)
324
0
{
325
0
  wr::DeviceUintSize wrSize;
326
0
  wrSize.width = aSize.width;
327
0
  wrSize.height = aSize.height;
328
0
  wr::DocumentHandle* newDoc;
329
0
330
0
  wr_api_create_document(mDocHandle, &newDoc, wrSize, aLayerIndex);
331
0
332
0
  RefPtr<WebRenderAPI> api(new WebRenderAPI(newDoc, mId,
333
0
                                            mMaxTextureSize,
334
0
                                            mUseANGLE,
335
0
                                            mUseDComp,
336
0
                                            mSyncHandle));
337
0
  api->mRootApi = this;
338
0
  return api.forget();
339
0
}
340
341
wr::WrIdNamespace
342
0
WebRenderAPI::GetNamespace() {
343
0
  return wr_api_get_namespace(mDocHandle);
344
0
}
345
346
WebRenderAPI::~WebRenderAPI()
347
0
{
348
0
  if (!mRootDocumentApi) {
349
0
    wr_api_delete_document(mDocHandle);
350
0
  }
351
0
352
0
  if (!mRootApi) {
353
0
    RenderThread::Get()->SetDestroyed(GetId());
354
0
355
0
    layers::SynchronousTask task("Destroy WebRenderAPI");
356
0
    auto event = MakeUnique<RemoveRenderer>(&task);
357
0
    RunOnRenderThread(std::move(event));
358
0
    task.Wait();
359
0
360
0
    wr_api_shut_down(mDocHandle);
361
0
  }
362
0
363
0
  wr_api_delete(mDocHandle);
364
0
}
365
366
void
367
WebRenderAPI::SendTransaction(TransactionBuilder& aTxn)
368
0
{
369
0
  wr_api_send_transaction(mDocHandle, aTxn.Raw(), aTxn.UseSceneBuilderThread());
370
0
}
371
372
bool
373
WebRenderAPI::HitTest(const wr::WorldPoint& aPoint,
374
                      wr::WrPipelineId& aOutPipelineId,
375
                      layers::FrameMetrics::ViewID& aOutScrollId,
376
                      gfx::CompositorHitTestInfo& aOutHitInfo)
377
0
{
378
0
  static_assert(sizeof(gfx::CompositorHitTestInfo) == sizeof(uint16_t),
379
0
                "CompositorHitTestInfo should be u16-sized");
380
0
  return wr_api_hit_test(mDocHandle, aPoint,
381
0
          &aOutPipelineId, &aOutScrollId, (uint16_t*)&aOutHitInfo);
382
0
}
383
384
void
385
WebRenderAPI::Readback(const TimeStamp& aStartTime,
386
                       gfx::IntSize size,
387
                       uint8_t *buffer,
388
                       uint32_t buffer_size)
389
0
{
390
0
    class Readback : public RendererEvent
391
0
    {
392
0
        public:
393
0
            explicit Readback(layers::SynchronousTask* aTask,
394
0
                              TimeStamp aStartTime,
395
0
                              gfx::IntSize aSize, uint8_t *aBuffer, uint32_t aBufferSize)
396
0
                : mTask(aTask)
397
0
                , mStartTime(aStartTime)
398
0
                , mSize(aSize)
399
0
                , mBuffer(aBuffer)
400
0
                , mBufferSize(aBufferSize)
401
0
            {
402
0
                MOZ_COUNT_CTOR(Readback);
403
0
            }
404
0
405
0
            ~Readback()
406
0
            {
407
0
                MOZ_COUNT_DTOR(Readback);
408
0
            }
409
0
410
0
            virtual void Run(RenderThread& aRenderThread, WindowId aWindowId) override
411
0
            {
412
0
                aRenderThread.UpdateAndRender(aWindowId, mStartTime, /* aReadback */ true);
413
0
                wr_renderer_readback(aRenderThread.GetRenderer(aWindowId)->GetRenderer(),
414
0
                                     mSize.width, mSize.height, mBuffer, mBufferSize);
415
0
                layers::AutoCompleteTask complete(mTask);
416
0
            }
417
0
418
0
            layers::SynchronousTask* mTask;
419
0
            TimeStamp mStartTime;
420
0
            gfx::IntSize mSize;
421
0
            uint8_t *mBuffer;
422
0
            uint32_t mBufferSize;
423
0
    };
424
0
425
0
    layers::SynchronousTask task("Readback");
426
0
    auto event = MakeUnique<Readback>(&task, aStartTime, size, buffer, buffer_size);
427
0
    // This event will be passed from wr_backend thread to renderer thread. That
428
0
    // implies that all frame data have been processed when the renderer runs this
429
0
    // read-back event. Then, we could make sure this read-back event gets the
430
0
    // latest result.
431
0
    RunOnRenderThread(std::move(event));
432
0
433
0
    task.Wait();
434
0
}
435
436
void
437
WebRenderAPI::ClearAllCaches()
438
0
{
439
0
  wr_api_clear_all_caches(mDocHandle);
440
0
}
441
442
void
443
WebRenderAPI::Pause()
444
0
{
445
0
    class PauseEvent : public RendererEvent
446
0
    {
447
0
        public:
448
0
            explicit PauseEvent(layers::SynchronousTask* aTask)
449
0
                : mTask(aTask)
450
0
            {
451
0
                MOZ_COUNT_CTOR(PauseEvent);
452
0
            }
453
0
454
0
            ~PauseEvent()
455
0
            {
456
0
                MOZ_COUNT_DTOR(PauseEvent);
457
0
            }
458
0
459
0
            virtual void Run(RenderThread& aRenderThread, WindowId aWindowId) override
460
0
            {
461
0
                aRenderThread.Pause(aWindowId);
462
0
                layers::AutoCompleteTask complete(mTask);
463
0
            }
464
0
465
0
            layers::SynchronousTask* mTask;
466
0
    };
467
0
468
0
    layers::SynchronousTask task("Pause");
469
0
    auto event = MakeUnique<PauseEvent>(&task);
470
0
    // This event will be passed from wr_backend thread to renderer thread. That
471
0
    // implies that all frame data have been processed when the renderer runs this event.
472
0
    RunOnRenderThread(std::move(event));
473
0
474
0
    task.Wait();
475
0
}
476
477
bool
478
WebRenderAPI::Resume()
479
0
{
480
0
    class ResumeEvent : public RendererEvent
481
0
    {
482
0
        public:
483
0
            explicit ResumeEvent(layers::SynchronousTask* aTask, bool* aResult)
484
0
                : mTask(aTask)
485
0
                , mResult(aResult)
486
0
            {
487
0
                MOZ_COUNT_CTOR(ResumeEvent);
488
0
            }
489
0
490
0
            ~ResumeEvent()
491
0
            {
492
0
                MOZ_COUNT_DTOR(ResumeEvent);
493
0
            }
494
0
495
0
            virtual void Run(RenderThread& aRenderThread, WindowId aWindowId) override
496
0
            {
497
0
                *mResult = aRenderThread.Resume(aWindowId);
498
0
                layers::AutoCompleteTask complete(mTask);
499
0
            }
500
0
501
0
            layers::SynchronousTask* mTask;
502
0
            bool* mResult;
503
0
    };
504
0
505
0
    bool result = false;
506
0
    layers::SynchronousTask task("Resume");
507
0
    auto event = MakeUnique<ResumeEvent>(&task, &result);
508
0
    // This event will be passed from wr_backend thread to renderer thread. That
509
0
    // implies that all frame data have been processed when the renderer runs this event.
510
0
    RunOnRenderThread(std::move(event));
511
0
512
0
    task.Wait();
513
0
    return result;
514
0
}
515
516
void
517
WebRenderAPI::NotifyMemoryPressure()
518
0
{
519
0
  wr_api_notify_memory_pressure(mDocHandle);
520
0
}
521
522
void
523
WebRenderAPI::AccumulateMemoryReport(MemoryReport* aReport)
524
0
{
525
0
  wr_api_accumulate_memory_report(mDocHandle, aReport);
526
0
}
527
528
void
529
WebRenderAPI::WakeSceneBuilder()
530
0
{
531
0
    wr_api_wake_scene_builder(mDocHandle);
532
0
}
533
534
void
535
WebRenderAPI::FlushSceneBuilder()
536
0
{
537
0
    wr_api_flush_scene_builder(mDocHandle);
538
0
}
539
540
void
541
WebRenderAPI::WaitFlushed()
542
0
{
543
0
    class WaitFlushedEvent : public RendererEvent
544
0
    {
545
0
        public:
546
0
            explicit WaitFlushedEvent(layers::SynchronousTask* aTask)
547
0
                : mTask(aTask)
548
0
            {
549
0
                MOZ_COUNT_CTOR(WaitFlushedEvent);
550
0
            }
551
0
552
0
            ~WaitFlushedEvent()
553
0
            {
554
0
                MOZ_COUNT_DTOR(WaitFlushedEvent);
555
0
            }
556
0
557
0
            virtual void Run(RenderThread& aRenderThread, WindowId aWindowId) override
558
0
            {
559
0
                layers::AutoCompleteTask complete(mTask);
560
0
            }
561
0
562
0
            layers::SynchronousTask* mTask;
563
0
    };
564
0
565
0
    layers::SynchronousTask task("WaitFlushed");
566
0
    auto event = MakeUnique<WaitFlushedEvent>(&task);
567
0
    // This event will be passed from wr_backend thread to renderer thread. That
568
0
    // implies that all frame data have been processed when the renderer runs this event.
569
0
    RunOnRenderThread(std::move(event));
570
0
571
0
    task.Wait();
572
0
}
573
574
void
575
WebRenderAPI::Capture()
576
0
{
577
0
  uint8_t bits = 3; //TODO: get from JavaScript
578
0
  const char* path = "wr-capture"; //TODO: get from JavaScript
579
0
  const char* border = "--------------------------\n";
580
0
  printf("%s Capturing WR state to: %s\n%s", border, path, border);
581
0
  wr_api_capture(mDocHandle, path, bits);
582
0
}
583
584
585
void
586
TransactionBuilder::Clear()
587
0
{
588
0
  wr_resource_updates_clear(mTxn);
589
0
}
590
591
void
592
0
TransactionBuilder::Notify(wr::Checkpoint aWhen, UniquePtr<NotificationHandler> aEvent) {
593
0
  wr_transaction_notify(mTxn, aWhen, reinterpret_cast<uintptr_t>(aEvent.release()));
594
0
}
595
596
void
597
TransactionBuilder::AddImage(ImageKey key, const ImageDescriptor& aDescriptor,
598
                             wr::Vec<uint8_t>& aBytes)
599
0
{
600
0
  wr_resource_updates_add_image(mTxn,
601
0
                                key,
602
0
                                &aDescriptor,
603
0
                                &aBytes.inner);
604
0
}
605
606
void
607
TransactionBuilder::AddBlobImage(ImageKey key, const ImageDescriptor& aDescriptor,
608
                                 wr::Vec<uint8_t>& aBytes)
609
0
{
610
0
  wr_resource_updates_add_blob_image(mTxn,
611
0
                                     key,
612
0
                                     &aDescriptor,
613
0
                                     &aBytes.inner);
614
0
}
615
616
void
617
TransactionBuilder::AddExternalImage(ImageKey key,
618
                                     const ImageDescriptor& aDescriptor,
619
                                     ExternalImageId aExtID,
620
                                     wr::WrExternalImageBufferType aBufferType,
621
                                     uint8_t aChannelIndex)
622
0
{
623
0
  wr_resource_updates_add_external_image(mTxn,
624
0
                                         key,
625
0
                                         &aDescriptor,
626
0
                                         aExtID,
627
0
                                         aBufferType,
628
0
                                         aChannelIndex);
629
0
}
630
631
void
632
TransactionBuilder::AddExternalImageBuffer(ImageKey aKey,
633
                                           const ImageDescriptor& aDescriptor,
634
                                           ExternalImageId aHandle)
635
0
{
636
0
  auto channelIndex = 0;
637
0
  AddExternalImage(aKey, aDescriptor, aHandle,
638
0
                   wr::WrExternalImageBufferType::ExternalBuffer,
639
0
                   channelIndex);
640
0
}
641
642
void
643
TransactionBuilder::UpdateImageBuffer(ImageKey aKey,
644
                                      const ImageDescriptor& aDescriptor,
645
                                      wr::Vec<uint8_t>& aBytes)
646
0
{
647
0
  wr_resource_updates_update_image(mTxn,
648
0
                                   aKey,
649
0
                                   &aDescriptor,
650
0
                                   &aBytes.inner);
651
0
}
652
653
void
654
TransactionBuilder::UpdateBlobImage(ImageKey aKey,
655
                                    const ImageDescriptor& aDescriptor,
656
                                    wr::Vec<uint8_t>& aBytes,
657
                                    const wr::DeviceUintRect& aDirtyRect)
658
0
{
659
0
  wr_resource_updates_update_blob_image(mTxn,
660
0
                                        aKey,
661
0
                                        &aDescriptor,
662
0
                                        &aBytes.inner,
663
0
                                        aDirtyRect);
664
0
}
665
666
void
667
TransactionBuilder::UpdateExternalImage(ImageKey aKey,
668
                                        const ImageDescriptor& aDescriptor,
669
                                        ExternalImageId aExtID,
670
                                        wr::WrExternalImageBufferType aBufferType,
671
                                        uint8_t aChannelIndex)
672
0
{
673
0
  wr_resource_updates_update_external_image(mTxn,
674
0
                                            aKey,
675
0
                                            &aDescriptor,
676
0
                                            aExtID,
677
0
                                            aBufferType,
678
0
                                            aChannelIndex);
679
0
}
680
681
void
682
TransactionBuilder::UpdateExternalImageWithDirtyRect(ImageKey aKey,
683
                                                     const ImageDescriptor& aDescriptor,
684
                                                     ExternalImageId aExtID,
685
                                                     wr::WrExternalImageBufferType aBufferType,
686
                                                     const wr::DeviceUintRect& aDirtyRect,
687
                                                     uint8_t aChannelIndex)
688
0
{
689
0
  wr_resource_updates_update_external_image_with_dirty_rect(mTxn,
690
0
                                                            aKey,
691
0
                                                            &aDescriptor,
692
0
                                                            aExtID,
693
0
                                                            aBufferType,
694
0
                                                            aChannelIndex,
695
0
                                                            aDirtyRect);
696
0
}
697
698
void TransactionBuilder::SetImageVisibleArea(ImageKey aKey, const wr::NormalizedRect& aArea)
699
0
{
700
0
  wr_resource_updates_set_image_visible_area(mTxn, aKey, &aArea);
701
0
}
702
703
void
704
TransactionBuilder::DeleteImage(ImageKey aKey)
705
0
{
706
0
  wr_resource_updates_delete_image(mTxn, aKey);
707
0
}
708
709
void
710
TransactionBuilder::AddRawFont(wr::FontKey aKey, wr::Vec<uint8_t>& aBytes, uint32_t aIndex)
711
0
{
712
0
  wr_resource_updates_add_raw_font(mTxn, aKey, &aBytes.inner, aIndex);
713
0
}
714
715
void
716
TransactionBuilder::AddFontDescriptor(wr::FontKey aKey, wr::Vec<uint8_t>& aBytes, uint32_t aIndex)
717
0
{
718
0
  wr_resource_updates_add_font_descriptor(mTxn, aKey, &aBytes.inner, aIndex);
719
0
}
720
721
void
722
TransactionBuilder::DeleteFont(wr::FontKey aKey)
723
0
{
724
0
  wr_resource_updates_delete_font(mTxn, aKey);
725
0
}
726
727
void
728
TransactionBuilder::AddFontInstance(wr::FontInstanceKey aKey,
729
                                    wr::FontKey aFontKey,
730
                                    float aGlyphSize,
731
                                    const wr::FontInstanceOptions* aOptions,
732
                                    const wr::FontInstancePlatformOptions* aPlatformOptions,
733
                                    wr::Vec<uint8_t>& aVariations)
734
0
{
735
0
  wr_resource_updates_add_font_instance(mTxn, aKey, aFontKey, aGlyphSize,
736
0
                                        aOptions, aPlatformOptions,
737
0
                                        &aVariations.inner);
738
0
}
739
740
void
741
TransactionBuilder::DeleteFontInstance(wr::FontInstanceKey aKey)
742
0
{
743
0
  wr_resource_updates_delete_font_instance(mTxn, aKey);
744
0
}
745
746
class FrameStartTime : public RendererEvent
747
{
748
public:
749
  explicit FrameStartTime(const TimeStamp& aTime)
750
    : mTime(aTime)
751
0
  {
752
0
    MOZ_COUNT_CTOR(FrameStartTime);
753
0
  }
754
755
  ~FrameStartTime()
756
0
  {
757
0
    MOZ_COUNT_DTOR(FrameStartTime);
758
0
  }
759
760
  virtual void Run(RenderThread& aRenderThread, WindowId aWindowId) override
761
0
  {
762
0
    auto renderer = aRenderThread.GetRenderer(aWindowId);
763
0
    if (renderer) {
764
0
      renderer->SetFrameStartTime(mTime);
765
0
    }
766
0
  }
767
768
private:
769
  TimeStamp mTime;
770
};
771
772
void
773
WebRenderAPI::SetFrameStartTime(const TimeStamp& aTime)
774
0
{
775
0
  auto event = MakeUnique<FrameStartTime>(aTime);
776
0
  RunOnRenderThread(std::move(event));
777
0
}
778
779
void
780
WebRenderAPI::RunOnRenderThread(UniquePtr<RendererEvent> aEvent)
781
0
{
782
0
  auto event = reinterpret_cast<uintptr_t>(aEvent.release());
783
0
  wr_api_send_external_event(mDocHandle, event);
784
0
}
785
786
DisplayListBuilder::DisplayListBuilder(PipelineId aId,
787
                                       const wr::LayoutSize& aContentSize,
788
                                       size_t aCapacity)
789
  : mActiveFixedPosTracker(nullptr)
790
0
{
791
0
  MOZ_COUNT_CTOR(DisplayListBuilder);
792
0
  mWrState = wr_state_new(aId, aContentSize, aCapacity);
793
0
}
794
795
DisplayListBuilder::~DisplayListBuilder()
796
0
{
797
0
  MOZ_COUNT_DTOR(DisplayListBuilder);
798
0
  wr_state_delete(mWrState);
799
0
}
800
801
0
void DisplayListBuilder::Save() { wr_dp_save(mWrState); }
802
0
void DisplayListBuilder::Restore() { wr_dp_restore(mWrState); }
803
0
void DisplayListBuilder::ClearSave() { wr_dp_clear_save(mWrState); }
804
805
usize DisplayListBuilder::Dump(usize aIndent,
806
                               const Maybe<usize>& aStart,
807
                               const Maybe<usize>& aEnd)
808
0
{
809
0
  return wr_dump_display_list(mWrState, aIndent, aStart.ptrOr(nullptr), aEnd.ptrOr(nullptr));
810
0
}
811
812
void
813
DisplayListBuilder::Finalize(wr::LayoutSize& aOutContentSize,
814
                             BuiltDisplayList& aOutDisplayList)
815
0
{
816
0
  wr_api_finalize_builder(mWrState,
817
0
                          &aOutContentSize,
818
0
                          &aOutDisplayList.dl_desc,
819
0
                          &aOutDisplayList.dl.inner);
820
0
}
821
822
Maybe<wr::WrClipId>
823
DisplayListBuilder::PushStackingContext(const wr::LayoutRect& aBounds,
824
                                        const wr::WrClipId* aClipNodeId,
825
                                        const WrAnimationProperty* aAnimation,
826
                                        const float* aOpacity,
827
                                        const gfx::Matrix4x4* aTransform,
828
                                        wr::TransformStyle aTransformStyle,
829
                                        const gfx::Matrix4x4* aPerspective,
830
                                        const wr::MixBlendMode& aMixBlendMode,
831
                                        const nsTArray<wr::WrFilterOp>& aFilters,
832
                                        bool aIsBackfaceVisible,
833
                                        const wr::RasterSpace& aRasterSpace)
834
0
{
835
0
  MOZ_ASSERT(mClipChainLeaf.isNothing(),
836
0
             "Non-empty leaf from clip chain given, but not used with SC!");
837
0
838
0
  wr::LayoutTransform matrix;
839
0
  if (aTransform) {
840
0
    matrix = ToLayoutTransform(*aTransform);
841
0
  }
842
0
  const wr::LayoutTransform* maybeTransform = aTransform ? &matrix : nullptr;
843
0
  wr::LayoutTransform perspective;
844
0
  if (aPerspective) {
845
0
    perspective = ToLayoutTransform(*aPerspective);
846
0
  }
847
0
848
0
  const wr::LayoutTransform* maybePerspective = aPerspective ? &perspective : nullptr;
849
0
  const size_t* maybeClipNodeId = aClipNodeId ? &aClipNodeId->id : nullptr;
850
0
  WRDL_LOG("PushStackingContext b=%s t=%s\n", mWrState, Stringify(aBounds).c_str(),
851
0
      aTransform ? Stringify(*aTransform).c_str() : "none");
852
0
853
0
  bool outIsReferenceFrame = false;
854
0
  uintptr_t outReferenceFrameId = 0;
855
0
  wr_dp_push_stacking_context(mWrState, aBounds, maybeClipNodeId, aAnimation,
856
0
                              aOpacity, maybeTransform, aTransformStyle,
857
0
                              maybePerspective, aMixBlendMode,
858
0
                              aFilters.Elements(), aFilters.Length(),
859
0
                              aIsBackfaceVisible, aRasterSpace,
860
0
                              &outIsReferenceFrame, &outReferenceFrameId);
861
0
  return outIsReferenceFrame ? Some(wr::WrClipId { outReferenceFrameId }) : Nothing();
862
0
}
863
864
void
865
DisplayListBuilder::PopStackingContext(bool aIsReferenceFrame)
866
0
{
867
0
  WRDL_LOG("PopStackingContext\n", mWrState);
868
0
  wr_dp_pop_stacking_context(mWrState, aIsReferenceFrame);
869
0
}
870
871
wr::WrClipChainId
872
DisplayListBuilder::DefineClipChain(const Maybe<wr::WrClipChainId>& aParent,
873
                                    const nsTArray<wr::WrClipId>& aClips)
874
0
{
875
0
  nsTArray<size_t> clipIds;
876
0
  for (wr::WrClipId id : aClips) {
877
0
    clipIds.AppendElement(id.id);
878
0
  }
879
0
  uint64_t clipchainId = wr_dp_define_clipchain(mWrState,
880
0
      aParent ? &(aParent->id) : nullptr,
881
0
      clipIds.Elements(), clipIds.Length());
882
0
  WRDL_LOG("DefineClipChain id=%" PRIu64 " p=%s clips=%zu\n", mWrState,
883
0
      clipchainId,
884
0
      aParent ? Stringify(aParent->id).c_str() : "(nil)",
885
0
      clipIds.Length());
886
0
  return wr::WrClipChainId{ clipchainId };
887
0
}
888
889
wr::WrClipId
890
DisplayListBuilder::DefineClip(const Maybe<wr::WrClipId>& aParentId,
891
                               const wr::LayoutRect& aClipRect,
892
                               const nsTArray<wr::ComplexClipRegion>* aComplex,
893
                               const wr::WrImageMask* aMask)
894
0
{
895
0
  size_t clip_id = wr_dp_define_clip(mWrState,
896
0
      aParentId ? &(aParentId->id) : nullptr,
897
0
      aClipRect,
898
0
      aComplex ? aComplex->Elements() : nullptr,
899
0
      aComplex ? aComplex->Length() : 0,
900
0
      aMask);
901
0
  WRDL_LOG("DefineClip id=%zu p=%s r=%s m=%p b=%s complex=%zu\n", mWrState,
902
0
      clip_id, aParentId ? Stringify(aParentId->id).c_str() : "(nil)",
903
0
      Stringify(aClipRect).c_str(), aMask,
904
0
      aMask ? Stringify(aMask->rect).c_str() : "none",
905
0
      aComplex ? aComplex->Length() : 0);
906
0
  return wr::WrClipId { clip_id };
907
0
}
908
909
void
910
DisplayListBuilder::PushClip(const wr::WrClipId& aClipId)
911
0
{
912
0
  WRDL_LOG("PushClip id=%zu\n", mWrState, aClipId.id);
913
0
  wr_dp_push_clip(mWrState, aClipId.id);
914
0
}
915
916
void
917
DisplayListBuilder::PopClip()
918
0
{
919
0
  WRDL_LOG("PopClip\n", mWrState);
920
0
  wr_dp_pop_clip(mWrState);
921
0
}
922
923
wr::WrClipId
924
DisplayListBuilder::DefineStickyFrame(const wr::LayoutRect& aContentRect,
925
                                      const float* aTopMargin,
926
                                      const float* aRightMargin,
927
                                      const float* aBottomMargin,
928
                                      const float* aLeftMargin,
929
                                      const StickyOffsetBounds& aVerticalBounds,
930
                                      const StickyOffsetBounds& aHorizontalBounds,
931
                                      const wr::LayoutVector2D& aAppliedOffset)
932
0
{
933
0
  size_t id = wr_dp_define_sticky_frame(mWrState, aContentRect, aTopMargin,
934
0
      aRightMargin, aBottomMargin, aLeftMargin, aVerticalBounds, aHorizontalBounds,
935
0
      aAppliedOffset);
936
0
  WRDL_LOG("DefineSticky id=%zu c=%s t=%s r=%s b=%s l=%s v=%s h=%s a=%s\n",
937
0
      mWrState, id,
938
0
      Stringify(aContentRect).c_str(),
939
0
      aTopMargin ? Stringify(*aTopMargin).c_str() : "none",
940
0
      aRightMargin ? Stringify(*aRightMargin).c_str() : "none",
941
0
      aBottomMargin ? Stringify(*aBottomMargin).c_str() : "none",
942
0
      aLeftMargin ? Stringify(*aLeftMargin).c_str() : "none",
943
0
      Stringify(aVerticalBounds).c_str(),
944
0
      Stringify(aHorizontalBounds).c_str(),
945
0
      Stringify(aAppliedOffset).c_str());
946
0
  return wr::WrClipId { id };
947
0
}
948
949
Maybe<wr::WrClipId>
950
DisplayListBuilder::GetScrollIdForDefinedScrollLayer(layers::FrameMetrics::ViewID aViewId) const
951
0
{
952
0
  if (aViewId == layers::FrameMetrics::NULL_SCROLL_ID) {
953
0
    return Some(wr::WrClipId::RootScrollNode());
954
0
  }
955
0
956
0
  auto it = mScrollIds.find(aViewId);
957
0
  if (it == mScrollIds.end()) {
958
0
    return Nothing();
959
0
  }
960
0
961
0
  return Some(it->second);
962
0
}
963
964
wr::WrClipId
965
DisplayListBuilder::DefineScrollLayer(const layers::FrameMetrics::ViewID& aViewId,
966
                                      const Maybe<wr::WrClipId>& aParentId,
967
                                      const wr::LayoutRect& aContentRect,
968
                                      const wr::LayoutRect& aClipRect)
969
0
{
970
0
  auto it = mScrollIds.find(aViewId);
971
0
  if (it != mScrollIds.end()) {
972
0
    return it->second;
973
0
  }
974
0
975
0
  // We haven't defined aViewId before, so let's define it now.
976
0
  size_t numericScrollId = wr_dp_define_scroll_layer(
977
0
      mWrState,
978
0
      aViewId,
979
0
      aParentId ? &(aParentId->id) : nullptr,
980
0
      aContentRect,
981
0
      aClipRect);
982
0
983
0
  WRDL_LOG("DefineScrollLayer id=%" PRIu64 "/%zu p=%s co=%s cl=%s\n", mWrState,
984
0
      aViewId, numericScrollId,
985
0
      aParentId ? Stringify(aParentId->id).c_str() : "(nil)",
986
0
      Stringify(aContentRect).c_str(), Stringify(aClipRect).c_str());
987
0
988
0
   auto clipId = wr::WrClipId { numericScrollId };
989
0
   mScrollIds[aViewId] = clipId;
990
0
   return clipId;
991
0
}
992
993
void
994
DisplayListBuilder::PushClipAndScrollInfo(const wr::WrClipId* aScrollId,
995
                                          const wr::WrClipChainId* aClipChainId,
996
                                          const Maybe<wr::LayoutRect>& aClipChainLeaf)
997
0
{
998
0
  if (aScrollId) {
999
0
    WRDL_LOG("PushClipAndScroll s=%zu c=%s\n", mWrState, aScrollId->id,
1000
0
        aClipChainId ? Stringify(aClipChainId->id).c_str() : "none");
1001
0
    wr_dp_push_clip_and_scroll_info(mWrState, aScrollId->id,
1002
0
        aClipChainId ? &(aClipChainId->id) : nullptr);
1003
0
  }
1004
0
  mClipChainLeaf = aClipChainLeaf;
1005
0
}
1006
1007
void
1008
DisplayListBuilder::PopClipAndScrollInfo(const wr::WrClipId* aScrollId)
1009
0
{
1010
0
  if (aScrollId) {
1011
0
    WRDL_LOG("PopClipAndScroll\n", mWrState);
1012
0
    wr_dp_pop_clip_and_scroll_info(mWrState);
1013
0
  }
1014
0
  mClipChainLeaf.reset();
1015
0
}
1016
1017
void
1018
DisplayListBuilder::PushRect(const wr::LayoutRect& aBounds,
1019
                             const wr::LayoutRect& aClip,
1020
                             bool aIsBackfaceVisible,
1021
                             const wr::ColorF& aColor)
1022
0
{
1023
0
  wr::LayoutRect clip = MergeClipLeaf(aClip);
1024
0
  WRDL_LOG("PushRect b=%s cl=%s c=%s\n", mWrState,
1025
0
      Stringify(aBounds).c_str(),
1026
0
      Stringify(clip).c_str(),
1027
0
      Stringify(aColor).c_str());
1028
0
  wr_dp_push_rect(mWrState, aBounds, clip,
1029
0
                  aIsBackfaceVisible, aColor);
1030
0
}
1031
1032
void
1033
DisplayListBuilder::PushClearRect(const wr::LayoutRect& aBounds)
1034
0
{
1035
0
  wr::LayoutRect clip = MergeClipLeaf(aBounds);
1036
0
  WRDL_LOG("PushClearRect b=%s c=%s\n", mWrState,
1037
0
      Stringify(aBounds).c_str(), Stringify(clip).c_str());
1038
0
  wr_dp_push_clear_rect(mWrState, aBounds, clip);
1039
0
}
1040
1041
void
1042
DisplayListBuilder::PushLinearGradient(const wr::LayoutRect& aBounds,
1043
                                       const wr::LayoutRect& aClip,
1044
                                       bool aIsBackfaceVisible,
1045
                                       const wr::LayoutPoint& aStartPoint,
1046
                                       const wr::LayoutPoint& aEndPoint,
1047
                                       const nsTArray<wr::GradientStop>& aStops,
1048
                                       wr::ExtendMode aExtendMode,
1049
                                       const wr::LayoutSize aTileSize,
1050
                                       const wr::LayoutSize aTileSpacing)
1051
0
{
1052
0
  wr_dp_push_linear_gradient(mWrState,
1053
0
                             aBounds, MergeClipLeaf(aClip),
1054
0
                             aIsBackfaceVisible,
1055
0
                             aStartPoint, aEndPoint,
1056
0
                             aStops.Elements(), aStops.Length(),
1057
0
                             aExtendMode,
1058
0
                             aTileSize, aTileSpacing);
1059
0
}
1060
1061
void
1062
DisplayListBuilder::PushRadialGradient(const wr::LayoutRect& aBounds,
1063
                                       const wr::LayoutRect& aClip,
1064
                                       bool aIsBackfaceVisible,
1065
                                       const wr::LayoutPoint& aCenter,
1066
                                       const wr::LayoutSize& aRadius,
1067
                                       const nsTArray<wr::GradientStop>& aStops,
1068
                                       wr::ExtendMode aExtendMode,
1069
                                       const wr::LayoutSize aTileSize,
1070
                                       const wr::LayoutSize aTileSpacing)
1071
0
{
1072
0
  wr_dp_push_radial_gradient(mWrState,
1073
0
                             aBounds, MergeClipLeaf(aClip),
1074
0
                             aIsBackfaceVisible,
1075
0
                             aCenter, aRadius,
1076
0
                             aStops.Elements(), aStops.Length(),
1077
0
                             aExtendMode,
1078
0
                             aTileSize, aTileSpacing);
1079
0
}
1080
1081
void
1082
DisplayListBuilder::PushImage(const wr::LayoutRect& aBounds,
1083
                              const wr::LayoutRect& aClip,
1084
                              bool aIsBackfaceVisible,
1085
                              wr::ImageRendering aFilter,
1086
                              wr::ImageKey aImage,
1087
                              bool aPremultipliedAlpha,
1088
                              const wr::ColorF& aColor)
1089
0
{
1090
0
  wr::LayoutSize size;
1091
0
  size.width = aBounds.size.width;
1092
0
  size.height = aBounds.size.height;
1093
0
  PushImage(aBounds, aClip, aIsBackfaceVisible, size, size,
1094
0
            aFilter, aImage, aPremultipliedAlpha, aColor);
1095
0
}
1096
1097
void
1098
DisplayListBuilder::PushImage(const wr::LayoutRect& aBounds,
1099
                              const wr::LayoutRect& aClip,
1100
                              bool aIsBackfaceVisible,
1101
                              const wr::LayoutSize& aStretchSize,
1102
                              const wr::LayoutSize& aTileSpacing,
1103
                              wr::ImageRendering aFilter,
1104
                              wr::ImageKey aImage,
1105
                              bool aPremultipliedAlpha,
1106
                              const wr::ColorF& aColor)
1107
0
{
1108
0
  wr::LayoutRect clip = MergeClipLeaf(aClip);
1109
0
  WRDL_LOG("PushImage b=%s cl=%s s=%s t=%s\n", mWrState,
1110
0
      Stringify(aBounds).c_str(),
1111
0
      Stringify(clip).c_str(), Stringify(aStretchSize).c_str(),
1112
0
      Stringify(aTileSpacing).c_str());
1113
0
  wr_dp_push_image(mWrState, aBounds, clip, aIsBackfaceVisible,
1114
0
                   aStretchSize, aTileSpacing, aFilter, aImage,
1115
0
                   aPremultipliedAlpha, aColor);
1116
0
}
1117
1118
void
1119
DisplayListBuilder::PushYCbCrPlanarImage(const wr::LayoutRect& aBounds,
1120
                                         const wr::LayoutRect& aClip,
1121
                                         bool aIsBackfaceVisible,
1122
                                         wr::ImageKey aImageChannel0,
1123
                                         wr::ImageKey aImageChannel1,
1124
                                         wr::ImageKey aImageChannel2,
1125
                                         wr::WrYuvColorSpace aColorSpace,
1126
                                         wr::ImageRendering aRendering)
1127
0
{
1128
0
  wr_dp_push_yuv_planar_image(mWrState,
1129
0
                              aBounds,
1130
0
                              MergeClipLeaf(aClip),
1131
0
                              aIsBackfaceVisible,
1132
0
                              aImageChannel0,
1133
0
                              aImageChannel1,
1134
0
                              aImageChannel2,
1135
0
                              aColorSpace,
1136
0
                              aRendering);
1137
0
}
1138
1139
void
1140
DisplayListBuilder::PushNV12Image(const wr::LayoutRect& aBounds,
1141
                                  const wr::LayoutRect& aClip,
1142
                                  bool aIsBackfaceVisible,
1143
                                  wr::ImageKey aImageChannel0,
1144
                                  wr::ImageKey aImageChannel1,
1145
                                  wr::WrYuvColorSpace aColorSpace,
1146
                                  wr::ImageRendering aRendering)
1147
0
{
1148
0
  wr_dp_push_yuv_NV12_image(mWrState,
1149
0
                            aBounds,
1150
0
                            MergeClipLeaf(aClip),
1151
0
                            aIsBackfaceVisible,
1152
0
                            aImageChannel0,
1153
0
                            aImageChannel1,
1154
0
                            aColorSpace,
1155
0
                            aRendering);
1156
0
}
1157
1158
void
1159
DisplayListBuilder::PushYCbCrInterleavedImage(const wr::LayoutRect& aBounds,
1160
                                              const wr::LayoutRect& aClip,
1161
                                              bool aIsBackfaceVisible,
1162
                                              wr::ImageKey aImageChannel0,
1163
                                              wr::WrYuvColorSpace aColorSpace,
1164
                                              wr::ImageRendering aRendering)
1165
0
{
1166
0
  wr_dp_push_yuv_interleaved_image(mWrState,
1167
0
                                   aBounds,
1168
0
                                   MergeClipLeaf(aClip),
1169
0
                                   aIsBackfaceVisible,
1170
0
                                   aImageChannel0,
1171
0
                                   aColorSpace,
1172
0
                                   aRendering);
1173
0
}
1174
1175
void
1176
DisplayListBuilder::PushIFrame(const wr::LayoutRect& aBounds,
1177
                               bool aIsBackfaceVisible,
1178
                               PipelineId aPipeline,
1179
                               bool aIgnoreMissingPipeline)
1180
0
{
1181
0
  wr_dp_push_iframe(mWrState, aBounds, MergeClipLeaf(aBounds),
1182
0
                    aIsBackfaceVisible, aPipeline, aIgnoreMissingPipeline);
1183
0
}
1184
1185
void
1186
DisplayListBuilder::PushBorder(const wr::LayoutRect& aBounds,
1187
                               const wr::LayoutRect& aClip,
1188
                               bool aIsBackfaceVisible,
1189
                               const wr::LayoutSideOffsets& aWidths,
1190
                               const Range<const wr::BorderSide>& aSides,
1191
                               const wr::BorderRadius& aRadius)
1192
0
{
1193
0
  MOZ_ASSERT(aSides.length() == 4);
1194
0
  if (aSides.length() != 4) {
1195
0
    return;
1196
0
  }
1197
0
  wr_dp_push_border(mWrState, aBounds, MergeClipLeaf(aClip), aIsBackfaceVisible,
1198
0
                    aWidths, aSides[0], aSides[1], aSides[2], aSides[3], aRadius);
1199
0
}
1200
1201
void
1202
DisplayListBuilder::PushBorderImage(const wr::LayoutRect& aBounds,
1203
                                    const wr::LayoutRect& aClip,
1204
                                    bool aIsBackfaceVisible,
1205
                                    const wr::LayoutSideOffsets& aWidths,
1206
                                    wr::ImageKey aImage,
1207
                                    const uint32_t aWidth,
1208
                                    const uint32_t aHeight,
1209
                                    const wr::SideOffsets2D<uint32_t>& aSlice,
1210
                                    const wr::SideOffsets2D<float>& aOutset,
1211
                                    const wr::RepeatMode& aRepeatHorizontal,
1212
                                    const wr::RepeatMode& aRepeatVertical)
1213
0
{
1214
0
  wr_dp_push_border_image(mWrState, aBounds, MergeClipLeaf(aClip),
1215
0
                          aIsBackfaceVisible, aWidths, aImage, aWidth, aHeight,
1216
0
                          aSlice, aOutset, aRepeatHorizontal, aRepeatVertical);
1217
0
}
1218
1219
void
1220
DisplayListBuilder::PushBorderGradient(const wr::LayoutRect& aBounds,
1221
                                       const wr::LayoutRect& aClip,
1222
                                       bool aIsBackfaceVisible,
1223
                                       const wr::LayoutSideOffsets& aWidths,
1224
                                       const uint32_t aWidth,
1225
                                       const uint32_t aHeight,
1226
                                       const wr::SideOffsets2D<uint32_t>& aSlice,
1227
                                       const wr::LayoutPoint& aStartPoint,
1228
                                       const wr::LayoutPoint& aEndPoint,
1229
                                       const nsTArray<wr::GradientStop>& aStops,
1230
                                       wr::ExtendMode aExtendMode,
1231
                                       const wr::SideOffsets2D<float>& aOutset)
1232
0
{
1233
0
  wr_dp_push_border_gradient(mWrState, aBounds, MergeClipLeaf(aClip),
1234
0
                             aIsBackfaceVisible, aWidths, aWidth, aHeight,
1235
0
                             aSlice, aStartPoint, aEndPoint,
1236
0
                             aStops.Elements(), aStops.Length(),
1237
0
                             aExtendMode, aOutset);
1238
0
}
1239
1240
void
1241
DisplayListBuilder::PushBorderRadialGradient(const wr::LayoutRect& aBounds,
1242
                                             const wr::LayoutRect& aClip,
1243
                                             bool aIsBackfaceVisible,
1244
                                             const wr::LayoutSideOffsets& aWidths,
1245
                                             const wr::LayoutPoint& aCenter,
1246
                                             const wr::LayoutSize& aRadius,
1247
                                             const nsTArray<wr::GradientStop>& aStops,
1248
                                             wr::ExtendMode aExtendMode,
1249
                                             const wr::SideOffsets2D<float>& aOutset)
1250
0
{
1251
0
  wr_dp_push_border_radial_gradient(
1252
0
    mWrState, aBounds, MergeClipLeaf(aClip), aIsBackfaceVisible,
1253
0
    aWidths, aCenter, aRadius, aStops.Elements(), aStops.Length(),
1254
0
    aExtendMode, aOutset);
1255
0
}
1256
1257
void
1258
DisplayListBuilder::PushText(const wr::LayoutRect& aBounds,
1259
                             const wr::LayoutRect& aClip,
1260
                             bool aIsBackfaceVisible,
1261
                             const wr::ColorF& aColor,
1262
                             wr::FontInstanceKey aFontKey,
1263
                             Range<const wr::GlyphInstance> aGlyphBuffer,
1264
                             const wr::GlyphOptions* aGlyphOptions)
1265
0
{
1266
0
  wr_dp_push_text(mWrState, aBounds, MergeClipLeaf(aClip),
1267
0
                  aIsBackfaceVisible,
1268
0
                  aColor,
1269
0
                  aFontKey,
1270
0
                  &aGlyphBuffer[0], aGlyphBuffer.length(),
1271
0
                  aGlyphOptions);
1272
0
}
1273
1274
void
1275
DisplayListBuilder::PushLine(const wr::LayoutRect& aClip,
1276
                             bool aIsBackfaceVisible,
1277
                             const wr::Line& aLine)
1278
0
{
1279
0
  wr::LayoutRect clip = MergeClipLeaf(aClip);
1280
0
  wr_dp_push_line(mWrState, &clip, aIsBackfaceVisible,
1281
0
                  &aLine.bounds, aLine.wavyLineThickness, aLine.orientation,
1282
0
                  &aLine.color, aLine.style);
1283
0
}
1284
1285
void
1286
DisplayListBuilder::PushShadow(const wr::LayoutRect& aRect,
1287
                               const wr::LayoutRect& aClip,
1288
                               bool aIsBackfaceVisible,
1289
                               const wr::Shadow& aShadow)
1290
0
{
1291
0
  wr_dp_push_shadow(mWrState, aRect, MergeClipLeaf(aClip),
1292
0
                    aIsBackfaceVisible, aShadow);
1293
0
}
1294
1295
void
1296
DisplayListBuilder::PopAllShadows()
1297
0
{
1298
0
  wr_dp_pop_all_shadows(mWrState);
1299
0
}
1300
1301
void
1302
DisplayListBuilder::PushBoxShadow(const wr::LayoutRect& aRect,
1303
                                  const wr::LayoutRect& aClip,
1304
                                  bool aIsBackfaceVisible,
1305
                                  const wr::LayoutRect& aBoxBounds,
1306
                                  const wr::LayoutVector2D& aOffset,
1307
                                  const wr::ColorF& aColor,
1308
                                  const float& aBlurRadius,
1309
                                  const float& aSpreadRadius,
1310
                                  const wr::BorderRadius& aBorderRadius,
1311
                                  const wr::BoxShadowClipMode& aClipMode)
1312
0
{
1313
0
  wr_dp_push_box_shadow(mWrState, aRect, MergeClipLeaf(aClip),
1314
0
                        aIsBackfaceVisible, aBoxBounds, aOffset, aColor,
1315
0
                        aBlurRadius, aSpreadRadius, aBorderRadius,
1316
0
                        aClipMode);
1317
0
}
1318
1319
Maybe<layers::FrameMetrics::ViewID>
1320
DisplayListBuilder::GetContainingFixedPosScrollTarget(const ActiveScrolledRoot* aAsr)
1321
0
{
1322
0
  return mActiveFixedPosTracker
1323
0
      ? mActiveFixedPosTracker->GetScrollTargetForASR(aAsr)
1324
0
      : Nothing();
1325
0
}
1326
1327
void
1328
DisplayListBuilder::SetHitTestInfo(const layers::FrameMetrics::ViewID& aScrollId,
1329
                                   gfx::CompositorHitTestInfo aHitInfo)
1330
0
{
1331
0
  static_assert(sizeof(gfx::CompositorHitTestInfo) == sizeof(uint16_t),
1332
0
                "CompositorHitTestInfo should be u16-sized");
1333
0
  wr_set_item_tag(mWrState, aScrollId, static_cast<uint16_t>(aHitInfo));
1334
0
}
1335
1336
void
1337
DisplayListBuilder::ClearHitTestInfo()
1338
0
{
1339
0
  wr_clear_item_tag(mWrState);
1340
0
}
1341
1342
DisplayListBuilder::FixedPosScrollTargetTracker::FixedPosScrollTargetTracker(
1343
    DisplayListBuilder& aBuilder,
1344
    const ActiveScrolledRoot* aAsr,
1345
    layers::FrameMetrics::ViewID aScrollId)
1346
  : mParentTracker(aBuilder.mActiveFixedPosTracker)
1347
  , mBuilder(aBuilder)
1348
  , mAsr(aAsr)
1349
  , mScrollId(aScrollId)
1350
0
{
1351
0
  aBuilder.mActiveFixedPosTracker = this;
1352
0
}
1353
1354
DisplayListBuilder::FixedPosScrollTargetTracker::~FixedPosScrollTargetTracker()
1355
0
{
1356
0
  mBuilder.mActiveFixedPosTracker = mParentTracker;
1357
0
}
1358
1359
Maybe<layers::FrameMetrics::ViewID>
1360
DisplayListBuilder::FixedPosScrollTargetTracker::GetScrollTargetForASR(const ActiveScrolledRoot* aAsr)
1361
0
{
1362
0
  return aAsr == mAsr ? Some(mScrollId) : Nothing();
1363
0
}
1364
1365
} // namespace wr
1366
} // namespace mozilla
1367
1368
extern "C" {
1369
1370
0
void wr_transaction_notification_notified(uintptr_t aHandler, mozilla::wr::Checkpoint aWhen) {
1371
0
  auto handler = reinterpret_cast<mozilla::wr::NotificationHandler*>(aHandler);
1372
0
  handler->Notify(aWhen);
1373
0
  // TODO: it would be better to get a callback when the object is destroyed on the
1374
0
  // rust side and delete then.
1375
0
  delete handler;
1376
0
}
1377
1378
} // extern C