Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/gfx/vr/VRDisplayPresentation.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 "VRDisplayPresentation.h"
8
9
#include "mozilla/dom/DocGroup.h"
10
#include "mozilla/Unused.h"
11
#include "VRDisplayClient.h"
12
#include "VRLayerChild.h"
13
14
using namespace mozilla;
15
using namespace mozilla::gfx;
16
17
VRDisplayPresentation::VRDisplayPresentation(VRDisplayClient *aDisplayClient,
18
                                             const nsTArray<mozilla::dom::VRLayer>& aLayers,
19
                                             uint32_t aGroup)
20
  : mDisplayClient(aDisplayClient)
21
  , mDOMLayers(aLayers)
22
  , mGroup(aGroup)
23
0
{
24
0
  CreateLayers();
25
0
}
26
27
void
28
VRDisplayPresentation::UpdateLayers(const nsTArray<mozilla::dom::VRLayer>& aLayers)
29
0
{
30
0
  mDOMLayers = aLayers;
31
0
  CreateLayers();
32
0
}
33
34
uint32_t
35
VRDisplayPresentation::GetGroup() const
36
0
{
37
0
  return mGroup;
38
0
}
39
40
void
41
VRDisplayPresentation::CreateLayers()
42
0
{
43
0
  VRManagerChild *manager = VRManagerChild::Get();
44
0
  if (!manager) {
45
0
    // This should not happen, but let's log it and avoid a crash in case
46
0
    // of regression.
47
0
    NS_WARNING("VRManagerChild::Get returned null!");
48
0
    return;
49
0
  }
50
0
51
0
  unsigned int iLayer=0;
52
0
  for (dom::VRLayer& layer : mDOMLayers) {
53
0
    dom::HTMLCanvasElement* canvasElement = layer.mSource;
54
0
    if (!canvasElement) {
55
0
      /// XXX In the future we will support WebVR in WebWorkers here
56
0
      continue;
57
0
    }
58
0
59
0
    Rect leftBounds(0.0, 0.0, 0.5, 1.0);
60
0
    if (layer.mLeftBounds.Length() == 4) {
61
0
      leftBounds.SetRect(layer.mLeftBounds[0],
62
0
                         layer.mLeftBounds[1],
63
0
                         layer.mLeftBounds[2],
64
0
                         layer.mLeftBounds[3]);
65
0
    } else if (layer.mLeftBounds.Length() != 0) {
66
0
      /**
67
0
       * We ignore layers with an incorrect number of values.
68
0
       * In the future, VRDisplay.requestPresent may throw in
69
0
       * this case.  See https://github.com/w3c/webvr/issues/71
70
0
       */
71
0
      continue;
72
0
    }
73
0
74
0
    Rect rightBounds(0.5, 0.0, 0.5, 1.0);
75
0
    if (layer.mRightBounds.Length() == 4) {
76
0
      rightBounds.SetRect(layer.mRightBounds[0], 
77
0
                          layer.mRightBounds[1],
78
0
                          layer.mRightBounds[2],
79
0
                          layer.mRightBounds[3]);
80
0
    } else if (layer.mRightBounds.Length() != 0) {
81
0
      /**
82
0
       * We ignore layers with an incorrect number of values.
83
0
       * In the future, VRDisplay.requestPresent may throw in
84
0
       * this case.  See https://github.com/w3c/webvr/issues/71
85
0
       */
86
0
      continue;
87
0
    }
88
0
89
0
    nsCOMPtr<nsIEventTarget> target;
90
0
    nsIDocument* doc;
91
0
    doc = canvasElement->OwnerDoc();
92
0
    if (doc) {
93
0
      target = doc->EventTargetFor(TaskCategory::Other);
94
0
    }
95
0
96
0
    if (mLayers.Length() <= iLayer) {
97
0
      // Not enough layers, let's add one
98
0
      RefPtr<VRLayerChild> vrLayer =
99
0
        static_cast<VRLayerChild*>(manager->CreateVRLayer(mDisplayClient->GetDisplayInfo().GetDisplayID(),
100
0
                                                          target, mGroup));
101
0
      if (!vrLayer) {
102
0
        NS_WARNING("CreateVRLayer returned null!");
103
0
        continue;
104
0
      }
105
0
      vrLayer->Initialize(canvasElement, leftBounds, rightBounds);
106
0
      mLayers.AppendElement(vrLayer);
107
0
    } else {
108
0
      // We already have a layer, let's update it
109
0
      mLayers[iLayer]->Initialize(canvasElement, leftBounds, rightBounds);
110
0
    }
111
0
    iLayer++;
112
0
  }
113
0
114
0
  // Truncate any excess layers that weren't included in the updated list
115
0
  mLayers.SetLength(iLayer);
116
0
}
117
118
void
119
VRDisplayPresentation::DestroyLayers()
120
0
{
121
0
  for (VRLayerChild* layer : mLayers) {
122
0
    if (layer->IsIPCOpen()) {
123
0
      Unused << layer->SendDestroy();
124
0
    }
125
0
  }
126
0
  mLayers.Clear();
127
0
}
128
129
void
130
VRDisplayPresentation::GetDOMLayers(nsTArray<dom::VRLayer>& result)
131
0
{
132
0
  result = mDOMLayers;
133
0
}
134
135
VRDisplayPresentation::~VRDisplayPresentation()
136
0
{
137
0
  DestroyLayers();
138
0
  mDisplayClient->PresentationDestroyed();
139
0
}
140
141
void VRDisplayPresentation::SubmitFrame()
142
0
{
143
0
  for (VRLayerChild *layer : mLayers) {
144
0
    layer->SubmitFrame(mDisplayClient->GetDisplayInfo());
145
0
    break; // Currently only one layer supported, submit only the first
146
0
  }
147
0
}