Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/gfx/vr/ipc/VRLayerChild.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 "VRLayerChild.h"
8
#include "gfxPlatform.h"
9
#include "GLScreenBuffer.h"
10
#include "mozilla/layers/TextureClientSharedSurface.h"
11
#include "SharedSurface.h"                // for SharedSurface
12
#include "SharedSurfaceGL.h"              // for SharedSurface
13
#include "mozilla/layers/LayersMessages.h" // for TimedTexture
14
#include "nsICanvasRenderingContextInternal.h"
15
#include "mozilla/dom/HTMLCanvasElement.h"
16
#include "mozilla/layers/SyncObject.h" // for SyncObjectClient
17
18
namespace mozilla {
19
namespace gfx {
20
21
VRLayerChild::VRLayerChild()
22
  : mCanvasElement(nullptr)
23
  , mIPCOpen(false)
24
  , mLastSubmittedFrameId(0)
25
0
{
26
0
  MOZ_COUNT_CTOR(VRLayerChild);
27
0
}
28
29
VRLayerChild::~VRLayerChild()
30
0
{
31
0
  ClearSurfaces();
32
0
33
0
  MOZ_COUNT_DTOR(VRLayerChild);
34
0
}
35
36
void
37
VRLayerChild::Initialize(dom::HTMLCanvasElement* aCanvasElement,
38
                         const gfx::Rect& aLeftEyeRect, const gfx::Rect& aRightEyeRect)
39
0
{
40
0
  MOZ_ASSERT(aCanvasElement);
41
0
  mLeftEyeRect = aLeftEyeRect;
42
0
  mRightEyeRect = aRightEyeRect;
43
0
  if (mCanvasElement == nullptr) {
44
0
    mCanvasElement = aCanvasElement;
45
0
    VRManagerChild *vrmc = VRManagerChild::Get();
46
0
    vrmc->RunFrameRequestCallbacks();
47
0
  } else {
48
0
    mCanvasElement = aCanvasElement;
49
0
  }
50
0
}
51
52
void
53
VRLayerChild::SubmitFrame(const VRDisplayInfo& aDisplayInfo)
54
0
{
55
0
  uint64_t frameId = aDisplayInfo.GetFrameId();
56
0
57
0
  // aFrameId will not increment unless the previuosly submitted
58
0
  // frame was received by the VR thread and submitted to the VR
59
0
  // compositor.  We early-exit here in the event that SubmitFrame
60
0
  // was called twice for the same aFrameId.
61
0
  if (!mCanvasElement || frameId == mLastSubmittedFrameId) {
62
0
    return;
63
0
  }
64
0
65
0
  // Keep the SharedSurfaceTextureClient alive long enough for
66
0
  // 1 extra frame, accomodating overlapped asynchronous rendering.
67
0
  mLastFrameTexture = mThisFrameTexture;
68
0
69
#if defined(MOZ_WIDGET_ANDROID)
70
  /**
71
   * Do not blit WebGL to a SurfaceTexture until the last submitted frame is already processed
72
   * and the new frame poses are ready. SurfaceTextures need to be released in the VR render thread 
73
   * in order to allow to be used again in the WebGLContext GLScreenBuffer producer.
74
   * Not doing so causes some freezes, crashes or other undefined behaviour.
75
   */
76
  if (!mThisFrameTexture || aDisplayInfo.mDisplayState.mLastSubmittedFrameId == mLastSubmittedFrameId) {
77
      mThisFrameTexture = mCanvasElement->GetVRFrame();
78
  }
79
#else
80
  mThisFrameTexture = mCanvasElement->GetVRFrame();
81
0
#endif // defined(MOZ_WIDGET_ANDROID)
82
0
83
0
  mLastSubmittedFrameId = frameId;
84
0
85
0
  if (!mThisFrameTexture) {
86
0
    return;
87
0
  }
88
0
  VRManagerChild* vrmc = VRManagerChild::Get();
89
0
  layers::SyncObjectClient* syncObject = vrmc->GetSyncObject();
90
0
  mThisFrameTexture->SyncWithObject(syncObject);
91
0
  if (!gfxPlatform::GetPlatform()->DidRenderingDeviceReset()) {
92
0
    if (syncObject && syncObject->IsSyncObjectValid()) {
93
0
      syncObject->Synchronize();
94
0
    }
95
0
  }
96
0
97
0
  gl::SharedSurface* surf = mThisFrameTexture->Surf();
98
0
  if (surf->mType == gl::SharedSurfaceType::Basic) {
99
0
    gfxCriticalError() << "SharedSurfaceType::Basic not supported for WebVR";
100
0
    return;
101
0
  }
102
0
103
0
  layers::SurfaceDescriptor desc;
104
0
  if (!surf->ToSurfaceDescriptor(&desc)) {
105
0
    gfxCriticalError() << "SharedSurface::ToSurfaceDescriptor failed in VRLayerChild::SubmitFrame";
106
0
    return;
107
0
  }
108
0
109
0
  SendSubmitFrame(desc, frameId, mLeftEyeRect, mRightEyeRect);
110
0
}
111
112
bool
113
VRLayerChild::IsIPCOpen()
114
0
{
115
0
  return mIPCOpen;
116
0
}
117
118
void
119
VRLayerChild::ClearSurfaces()
120
0
{
121
0
  mThisFrameTexture = nullptr;
122
0
  mLastFrameTexture = nullptr;
123
0
}
124
125
void
126
VRLayerChild::ActorDestroy(ActorDestroyReason aWhy)
127
0
{
128
0
  mIPCOpen = false;
129
0
}
130
131
// static
132
PVRLayerChild*
133
VRLayerChild::CreateIPDLActor()
134
0
{
135
0
  VRLayerChild* c = new VRLayerChild();
136
0
  c->AddIPDLReference();
137
0
  return c;
138
0
}
139
140
// static
141
bool
142
VRLayerChild::DestroyIPDLActor(PVRLayerChild* actor)
143
0
{
144
0
  static_cast<VRLayerChild*>(actor)->ReleaseIPDLReference();
145
0
  return true;
146
0
}
147
148
void
149
0
VRLayerChild::AddIPDLReference() {
150
0
  MOZ_ASSERT(mIPCOpen == false);
151
0
  mIPCOpen = true;
152
0
  AddRef();
153
0
}
154
void
155
0
VRLayerChild::ReleaseIPDLReference() {
156
0
  MOZ_ASSERT(mIPCOpen == false);
157
0
  Release();
158
0
}
159
160
} // namespace gfx
161
} // namespace mozilla