Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement dynamic switch between flat and curved display #979

Merged
merged 1 commit into from
Mar 4, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -989,6 +989,7 @@ public void resetUIYaw() {
queueRunnable(this::resetUIYawNative);
}

@Override
public void setCylinderDensity(final float aDensity) {
queueRunnable(() -> setCylinderDensityNative(aDensity));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ interface WorldClickListener {
void showVRVideo(int aWindowHandle, @VideoProjectionMenuWidget.VideoProjectionFlags int aVideoProjection);
void hideVRVideo();
void resetUIYaw();
void setCylinderDensity(float aDensity);
void addFocusChangeListener(@NonNull FocusChangeListener aListener);
void removeFocusChangeListener(@NonNull FocusChangeListener aListener);
void addPermissionListener(PermissionListener aListener);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,9 @@ private void initialize(Context aContext) {
mCurvedDisplaySwitch = findViewById(R.id.curved_display_switch);
mCurvedDisplaySwitch.setChecked(SettingsStore.getInstance(getContext()).getCylinderDensity() > 0.0f);
mCurvedDisplaySwitch.setOnCheckedChangeListener((compoundButton, enabled, apply) -> {
SettingsStore.getInstance(getContext()).setCylinderDensity(enabled ? SettingsStore.CYLINDER_DENSITY_ENABLED_DEFAULT : 0.0f);
showRestartDialog();
float density = enabled ? SettingsStore.CYLINDER_DENSITY_ENABLED_DEFAULT : 0.0f;
SettingsStore.getInstance(getContext()).setCylinderDensity(density);
mWidgetManager.setCylinderDensity(density);
});

int uaMode = SettingsStore.getInstance(getContext()).getUaMode();
Expand Down
16 changes: 15 additions & 1 deletion app/src/main/cpp/BrowserWorld.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -933,7 +933,21 @@ void
BrowserWorld::SetCylinderDensity(const float aDensity) {
m.cylinderDensity = aDensity;
for (WidgetPtr& widget: m.widgets) {
widget->SetCylinderDensity(aDensity);
const bool useCylinder = m.cylinderDensity > 0 && widget->GetPlacement()->cylinder;
if (useCylinder && widget->GetCylinder()) {
widget->SetCylinderDensity(aDensity);
} else if (useCylinder && !widget->GetCylinder()) {
VRLayerCylinderPtr layer = m.device->CreateLayerCylinder(widget->GetLayer());
CylinderPtr cylinder = Cylinder::Create(m.create, layer);
widget->SetCylinder(cylinder);
widget->SetCylinderDensity(aDensity);
} else if (widget->GetCylinder()) {
float w = 0, h = 0;
widget->GetWorldSize(w, h);
VRLayerQuadPtr layer = m.device->CreateLayerQuad(widget->GetLayer());
QuadPtr quad = Quad::Create(m.create, w, h, layer);
widget->SetQuad(quad);
}
}
}

Expand Down
2 changes: 2 additions & 0 deletions app/src/main/cpp/DeviceDelegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,10 @@ class DeviceDelegate {
virtual void EndFrame(bool aDiscard = false) = 0;
virtual VRLayerQuadPtr CreateLayerQuad(int32_t aWidth, int32_t aHeight,
VRLayerSurface::SurfaceType aSurfaceType) { return nullptr; }
virtual VRLayerQuadPtr CreateLayerQuad(const VRLayerSurfacePtr& aMoveLayer) { return nullptr; }
virtual VRLayerCylinderPtr CreateLayerCylinder(int32_t aWidth, int32_t aHeight,
VRLayerSurface::SurfaceType aSurfaceType) { return nullptr; }
virtual VRLayerCylinderPtr CreateLayerCylinder(const VRLayerSurfacePtr& aMoveLayer) { return nullptr; }
virtual VRLayerCubePtr CreateLayerCube(int32_t aWidth, int32_t aHeight, GLint aInternalFormat) { return nullptr; }
virtual VRLayerEquirectPtr CreateLayerEquirect(const VRLayerPtr &aSource) { return nullptr; }
virtual void DeleteLayer(const VRLayerPtr& aLayer) {};
Expand Down
87 changes: 69 additions & 18 deletions app/src/main/cpp/Widget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,23 +62,7 @@ struct Widget::State {
quad = aQuad;
cylinder = aCylinder;

VRLayerPtr layer = GetLayer();

if (layer) {
layer->SetSurfaceChangedDelegate([=](const VRLayer& aLayer, VRLayer::SurfaceChange aChange, const std::function<void()>& aCallback) {
const VRLayerQuad& layerQuad = static_cast<const VRLayerQuad&>(aLayer);
VRBrowser::DispatchCreateWidgetLayer((jint)aHandle, layerQuad.GetSurface(), layerQuad.GetWidth(), layerQuad.GetHeight(), aCallback);
});
} else {
surface = vrb::TextureSurface::Create(render, name);
if (quad) {
quad->SetTexture(surface, aTextureWidth, aTextureHeight);
quad->SetMaterial(vrb::Color(0.4f, 0.4f, 0.4f), vrb::Color(1.0f, 1.0f, 1.0f), vrb::Color(0.0f, 0.0f, 0.0f), 0.0f);
} else if (cylinder) {
cylinder->SetTexture(surface, aTextureWidth, aTextureHeight);
cylinder->SetMaterial(vrb::Color(0.4f, 0.4f, 0.4f), vrb::Color(1.0f, 1.0f, 1.0f), vrb::Color(0.0f, 0.0f, 0.0f), 0.0f);
}
}
UpdateSurface(aTextureWidth, aTextureHeight);

vrb::CreationContextPtr create = render->GetRenderThreadCreationContext();
transform = vrb::Transform::Create(create);
Expand All @@ -90,14 +74,36 @@ struct Widget::State {
transform->AddNode(cylinder->GetRoot());
}

if (layer) {
if (GetLayer()) {
toggleState = true;
root->ToggleAll(true);
} else {
root->ToggleAll(false);
}
}

void UpdateSurface(const int32_t aTextureWidth, const int32_t aTextureHeight) {
VRLayerPtr layer = GetLayer();
if (layer) {
layer->SetSurfaceChangedDelegate([=](const VRLayer& aLayer, VRLayer::SurfaceChange aChange, const std::function<void()>& aCallback) {
const VRLayerQuad& layerQuad = static_cast<const VRLayerQuad&>(aLayer);
VRBrowser::DispatchCreateWidgetLayer((jint)handle, layerQuad.GetSurface(), layerQuad.GetWidth(), layerQuad.GetHeight(), aCallback);
});
} else {
if (!surface) {
vrb::RenderContextPtr render = context.lock();
surface = vrb::TextureSurface::Create(render, name);
}
if (quad) {
quad->SetTexture(surface, aTextureWidth, aTextureHeight);
quad->SetMaterial(vrb::Color(0.4f, 0.4f, 0.4f), vrb::Color(1.0f, 1.0f, 1.0f), vrb::Color(0.0f, 0.0f, 0.0f), 0.0f);
} else if (cylinder) {
cylinder->SetTexture(surface, aTextureWidth, aTextureHeight);
cylinder->SetMaterial(vrb::Color(0.4f, 0.4f, 0.4f), vrb::Color(1.0f, 1.0f, 1.0f), vrb::Color(0.0f, 0.0f, 0.0f), 0.0f);
}
}
}

bool FirstDraw() {
if (!placement) {
return false;
Expand Down Expand Up @@ -150,6 +156,13 @@ struct Widget::State {
cylinder->SetTransform(translation.PostMultiply(scaleMatrix));
}
}

void RemoveResizer() {
if (resizer) {
resizer->GetRoot()->RemoveFromParents();
resizer = nullptr;
}
}
};

WidgetPtr
Expand Down Expand Up @@ -326,6 +339,44 @@ Widget::GetCylinder() const {
return m.cylinder;
}

void
Widget::SetQuad(const QuadPtr& aQuad) const {
int32_t textureWidth, textureHeight;
GetSurfaceTextureSize(textureWidth, textureHeight);
if (m.cylinder) {
m.cylinder->GetRoot()->RemoveFromParents();
m.cylinder = nullptr;
}
if (m.quad) {
m.quad->GetRoot()->RemoveFromParents();
}

m.quad = aQuad;
m.transform->AddNode(aQuad->GetRoot());

m.RemoveResizer();
m.UpdateSurface(textureWidth, textureHeight);
}

void
Widget::SetCylinder(const CylinderPtr& aCylinder) const {
int32_t textureWidth, textureHeight;
GetSurfaceTextureSize(textureWidth, textureHeight);
if (m.quad) {
m.quad->GetRoot()->RemoveFromParents();
m.quad = nullptr;
}
if (m.cylinder) {
m.cylinder->GetRoot()->RemoveFromParents();
}

m.cylinder = aCylinder;
m.transform->AddNode(aCylinder->GetRoot());

m.RemoveResizer();
m.UpdateSurface(textureWidth, textureHeight);
}

VRLayerSurfacePtr
Widget::GetLayer() const {
return m.GetLayer();
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/cpp/Widget.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ class Widget {
vrb::NodePtr GetRoot() const;
QuadPtr GetQuad() const;
CylinderPtr GetCylinder() const;
void SetQuad(const QuadPtr& aQuad) const;
void SetCylinder(const CylinderPtr& aCylinder) const;
VRLayerSurfacePtr GetLayer() const;
vrb::TransformPtr GetTransformNode() const;
const WidgetPlacementPtr& GetPlacement() const;
Expand Down
74 changes: 68 additions & 6 deletions app/src/oculusvr/cpp/DeviceDelegateOculusVR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -225,14 +225,13 @@ class OculusLayerSurface: public OculusLayerBase<T, U> {
OculusLayer::BindDelegate bindDelegate;

void Init(JNIEnv * aEnv, vrb::RenderContextPtr& aContext) override {
if (this->swapChain) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does Init() get called multiple times? How can the device have a valid swap chain before calling Init()?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Init can be called from pause/resume life cycle events, and also just after a layer is created when the activity is already active in VR.

return;
}

this->jniEnv = aEnv;
this->contextWeak = aContext;
this->ovrLayer.Header.SrcBlend = VRAPI_FRAME_LAYER_BLEND_ONE;
this->ovrLayer.Header.DstBlend = VRAPI_FRAME_LAYER_BLEND_ONE_MINUS_SRC_ALPHA;
if (this->swapChain) {
return;
}

InitSwapChain(this->swapChain, this->surface, this->fbo);
this->layer->SetResizeDelegate([=]{
Expand Down Expand Up @@ -285,6 +284,19 @@ class OculusLayerSurface: public OculusLayerBase<T, U> {
});
}

protected:
void TakeSurface(const OculusLayerPtr& aSource) {
this->swapChain = aSource->GetSwapChain();
VRLayerSurfacePtr sourceLayer = std::dynamic_pointer_cast<VRLayerSurface>(aSource->GetLayer());
if (sourceLayer) {
this->surface = sourceLayer->GetSurface();
}
this->composited = aSource->IsComposited();
this->layer->SetInitialized(aSource->GetLayer()->IsInitialized());
this->layer->SetResizeDelegate([=]{
Resize();
});
}
private:
void InitSwapChain(ovrTextureSwapChain*& swapChainOut, jobject & surfaceOut, vrb::FBOPtr& fboOut) {
if (this->layer->GetSurfaceType() == VRLayerQuad::SurfaceType::AndroidSurface) {
Expand Down Expand Up @@ -325,9 +337,12 @@ typedef std::shared_ptr<OculusLayerQuad> OculusLayerQuadPtr;

class OculusLayerQuad: public OculusLayerSurface<VRLayerQuadPtr, ovrLayerProjection2> {
public:
static OculusLayerQuadPtr Create(const VRLayerQuadPtr& aLayer) {
static OculusLayerQuadPtr Create(const VRLayerQuadPtr& aLayer, const OculusLayerPtr& aSource = nullptr) {
auto result = std::make_shared<OculusLayerQuad>();
result->layer = aLayer;
if (aSource) {
result->TakeSurface(aSource);
}
return result;
}

Expand Down Expand Up @@ -374,9 +389,12 @@ typedef std::shared_ptr<OculusLayerCylinder> OculusLayerCylinderPtr;

class OculusLayerCylinder: public OculusLayerSurface<VRLayerCylinderPtr, ovrLayerCylinder2> {
public:
static OculusLayerCylinderPtr Create(const VRLayerCylinderPtr& aLayer) {
static OculusLayerCylinderPtr Create(const VRLayerCylinderPtr& aLayer, const OculusLayerPtr& aSource = nullptr) {
auto result = std::make_shared<OculusLayerCylinder>();
result->layer = aLayer;
if (aSource) {
result->TakeSurface(aSource);
}
return result;
}

Expand Down Expand Up @@ -1227,6 +1245,28 @@ DeviceDelegateOculusVR::CreateLayerQuad(int32_t aWidth, int32_t aHeight,
return layer;
}

VRLayerQuadPtr
DeviceDelegateOculusVR::CreateLayerQuad(const VRLayerSurfacePtr& aMoveLayer) {
if (!m.layersEnabled) {
return nullptr;
}

VRLayerQuadPtr layer = VRLayerQuad::Create(aMoveLayer->GetWidth(), aMoveLayer->GetHeight(), aMoveLayer->GetSurfaceType());
OculusLayerQuadPtr oculusLayer;

for (int i = 0; i < m.uiLayers.size(); ++i) {
if (m.uiLayers[i]->GetLayer() == aMoveLayer) {
oculusLayer = OculusLayerQuad::Create(layer, m.uiLayers[i]);
m.uiLayers.erase(m.uiLayers.begin() + i);
break;
}
}
if (oculusLayer) {
m.AddUILayer(oculusLayer, aMoveLayer->GetSurfaceType());
}
return layer;
}

VRLayerCylinderPtr
DeviceDelegateOculusVR::CreateLayerCylinder(int32_t aWidth, int32_t aHeight,
VRLayerSurface::SurfaceType aSurfaceType) {
Expand All @@ -1239,6 +1279,28 @@ DeviceDelegateOculusVR::CreateLayerCylinder(int32_t aWidth, int32_t aHeight,
return layer;
}

VRLayerCylinderPtr
DeviceDelegateOculusVR::CreateLayerCylinder(const VRLayerSurfacePtr& aMoveLayer) {
if (!m.layersEnabled) {
return nullptr;
}

VRLayerCylinderPtr layer = VRLayerCylinder::Create(aMoveLayer->GetWidth(), aMoveLayer->GetHeight(), aMoveLayer->GetSurfaceType());
OculusLayerCylinderPtr oculusLayer;

for (int i = 0; i < m.uiLayers.size(); ++i) {
if (m.uiLayers[i]->GetLayer() == aMoveLayer) {
oculusLayer = OculusLayerCylinder::Create(layer, m.uiLayers[i]);
m.uiLayers.erase(m.uiLayers.begin() + i);
break;
}
}
if (oculusLayer) {
m.AddUILayer(oculusLayer, aMoveLayer->GetSurfaceType());
}
return layer;
}


VRLayerCubePtr
DeviceDelegateOculusVR::CreateLayerCube(int32_t aWidth, int32_t aHeight, GLint aInternalFormat) {
Expand Down
2 changes: 2 additions & 0 deletions app/src/oculusvr/cpp/DeviceDelegateOculusVR.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,10 @@ class DeviceDelegateOculusVR : public DeviceDelegate {
void EndFrame(const bool aDiscard) override;
VRLayerQuadPtr CreateLayerQuad(int32_t aWidth, int32_t aHeight,
VRLayerSurface::SurfaceType aSurfaceType) override;
VRLayerQuadPtr CreateLayerQuad(const VRLayerSurfacePtr& aMoveLayer) override;
VRLayerCylinderPtr CreateLayerCylinder(int32_t aWidth, int32_t aHeight,
VRLayerSurface::SurfaceType aSurfaceType) override;
VRLayerCylinderPtr CreateLayerCylinder(const VRLayerSurfacePtr& aMoveLayer) override;
VRLayerCubePtr CreateLayerCube(int32_t aWidth, int32_t aHeight, GLint aInternalFormat) override;
VRLayerEquirectPtr CreateLayerEquirect(const VRLayerPtr &aSource) override;
void DeleteLayer(const VRLayerPtr& aLayer) override;
Expand Down