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