tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

VRDisplayPresentation.cpp (4894B)


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