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 "GLScreenBuffer.h"
9 #include "mozilla/layers/TextureClientSharedSurface.h"
10 #include "SharedSurface.h"                  // for SharedSurface
11 #include "SharedSurfaceGL.h"                // for SharedSurface
12 #include "mozilla/layers/LayersMessages.h"  // for TimedTexture
13 #include "nsICanvasRenderingContextInternal.h"
14 #include "mozilla/dom/HTMLCanvasElement.h"
15 #include "mozilla/layers/SyncObject.h"  // for SyncObjectClient
16 
17 namespace mozilla {
18 namespace gfx {
19 
VRLayerChild()20 VRLayerChild::VRLayerChild()
21     : mCanvasElement(nullptr), mIPCOpen(false), mLastSubmittedFrameId(0) {
22   MOZ_COUNT_CTOR(VRLayerChild);
23 }
24 
~VRLayerChild()25 VRLayerChild::~VRLayerChild() {
26   ClearSurfaces();
27 
28   MOZ_COUNT_DTOR(VRLayerChild);
29 }
30 
Initialize(dom::HTMLCanvasElement * aCanvasElement,const gfx::Rect & aLeftEyeRect,const gfx::Rect & aRightEyeRect)31 void VRLayerChild::Initialize(dom::HTMLCanvasElement* aCanvasElement,
32                               const gfx::Rect& aLeftEyeRect,
33                               const gfx::Rect& aRightEyeRect) {
34   MOZ_ASSERT(aCanvasElement);
35   mLeftEyeRect = aLeftEyeRect;
36   mRightEyeRect = aRightEyeRect;
37   mCanvasElement = aCanvasElement;
38 }
39 
SubmitFrame(uint64_t aFrameId)40 void VRLayerChild::SubmitFrame(uint64_t aFrameId) {
41   // aFrameId will not increment unless the previuosly submitted
42   // frame was received by the VR thread and submitted to the VR
43   // compositor.  We early-exit here in the event that SubmitFrame
44   // was called twice for the same aFrameId.
45   if (!mCanvasElement || aFrameId == mLastSubmittedFrameId) {
46     return;
47   }
48   mLastSubmittedFrameId = aFrameId;
49 
50   // Keep the SharedSurfaceTextureClient alive long enough for
51   // 1 extra frame, accomodating overlapped asynchronous rendering.
52   mLastFrameTexture = mThisFrameTexture;
53 
54   mThisFrameTexture = mCanvasElement->GetVRFrame();
55   if (!mThisFrameTexture) {
56     return;
57   }
58   VRManagerChild* vrmc = VRManagerChild::Get();
59   layers::SyncObjectClient* syncObject = vrmc->GetSyncObject();
60   mThisFrameTexture->SyncWithObject(syncObject);
61   if (!gfxPlatform::GetPlatform()->DidRenderingDeviceReset()) {
62     if (syncObject && syncObject->IsSyncObjectValid()) {
63       syncObject->Synchronize();
64     }
65   }
66 
67   gl::SharedSurface* surf = mThisFrameTexture->Surf();
68   if (surf->mType == gl::SharedSurfaceType::Basic) {
69     gfxCriticalError() << "SharedSurfaceType::Basic not supported for WebVR";
70     return;
71   }
72 
73   layers::SurfaceDescriptor desc;
74   if (!surf->ToSurfaceDescriptor(&desc)) {
75     gfxCriticalError() << "SharedSurface::ToSurfaceDescriptor failed in "
76                           "VRLayerChild::SubmitFrame";
77     return;
78   }
79 
80   SendSubmitFrame(desc, aFrameId, mLeftEyeRect, mRightEyeRect);
81 }
82 
IsIPCOpen()83 bool VRLayerChild::IsIPCOpen() { return mIPCOpen; }
84 
ClearSurfaces()85 void VRLayerChild::ClearSurfaces() {
86   mThisFrameTexture = nullptr;
87   mLastFrameTexture = nullptr;
88 }
89 
ActorDestroy(ActorDestroyReason aWhy)90 void VRLayerChild::ActorDestroy(ActorDestroyReason aWhy) { mIPCOpen = false; }
91 
92 // static
CreateIPDLActor()93 PVRLayerChild* VRLayerChild::CreateIPDLActor() {
94   VRLayerChild* c = new VRLayerChild();
95   c->AddIPDLReference();
96   return c;
97 }
98 
99 // static
DestroyIPDLActor(PVRLayerChild * actor)100 bool VRLayerChild::DestroyIPDLActor(PVRLayerChild* actor) {
101   static_cast<VRLayerChild*>(actor)->ReleaseIPDLReference();
102   return true;
103 }
104 
AddIPDLReference()105 void VRLayerChild::AddIPDLReference() {
106   MOZ_ASSERT(mIPCOpen == false);
107   mIPCOpen = true;
108   AddRef();
109 }
ReleaseIPDLReference()110 void VRLayerChild::ReleaseIPDLReference() {
111   MOZ_ASSERT(mIPCOpen == false);
112   Release();
113 }
114 
115 }  // namespace gfx
116 }  // namespace mozilla
117