blob: 6e817420c5145d590b1aa161bdf3ddb97282e4b7 [file]
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "device/vr/openxr/openxr_view_configuration.h"
#include "base/check_op.h"
#include "third_party/openxr/src/include/openxr/openxr.h"
namespace device {
OpenXrViewConfiguration::OpenXrViewConfiguration() = default;
OpenXrViewConfiguration::OpenXrViewConfiguration(OpenXrViewConfiguration&&) =
default;
OpenXrViewConfiguration::OpenXrViewConfiguration(
const OpenXrViewConfiguration&) = default;
OpenXrViewConfiguration& OpenXrViewConfiguration::operator=(
const OpenXrViewConfiguration&) = default;
OpenXrViewConfiguration::~OpenXrViewConfiguration() = default;
// Used only for testing - initializes an OpenXR view configuration that the
// mock OpenXR runtime supports.
OpenXrViewConfiguration::OpenXrViewConfiguration(XrViewConfigurationType type,
bool active,
uint32_t num_views,
uint32_t dimension,
uint32_t swap_count) {
const XrViewConfigurationView kViewConfigurationView = {
XR_TYPE_VIEW_CONFIGURATION_VIEW,
nullptr,
dimension,
dimension,
dimension,
dimension,
swap_count,
swap_count};
std::vector<XrViewConfigurationView> view_properties(num_views);
for (uint32_t i = 0; i < num_views; i++) {
view_properties[i] = kViewConfigurationView;
}
Initialize(type, std::move(view_properties));
SetActive(active);
}
void OpenXrViewConfiguration::Initialize(
XrViewConfigurationType type,
std::vector<XrViewConfigurationView> properties) {
DCHECK(!initialized_);
DCHECK(!properties.empty());
type_ = type;
active_ = false;
viewport_ = gfx::Rect();
properties_ = std::move(properties);
local_from_view_.resize(properties_.size());
projection_views_.resize(properties_.size());
initialized_ = true;
}
bool OpenXrViewConfiguration::Initialized() const {
return initialized_;
}
XrViewConfigurationType OpenXrViewConfiguration::Type() const {
return type_;
}
void OpenXrViewConfiguration::SetActive(bool active) {
active_ = active;
if (!active_) {
viewport_ = gfx::Rect();
}
}
bool OpenXrViewConfiguration::Active() const {
return active_;
}
const gfx::Rect& OpenXrViewConfiguration::Viewport() const {
return viewport_;
}
void OpenXrViewConfiguration::SetViewport(uint32_t x,
uint32_t y,
uint32_t width,
uint32_t height) {
viewport_ = gfx::Rect(x, y, width, height);
}
const std::vector<XrViewConfigurationView>&
OpenXrViewConfiguration::Properties() const {
return properties_;
}
void OpenXrViewConfiguration::SetProperties(
std::vector<XrViewConfigurationView> properties) {
// The number of views in a view configuration should not change throughout
// the lifetime of the OpenXR instance.
DCHECK_EQ(properties.size(), properties_.size());
properties_ = std::move(properties);
}
const std::vector<XrView>& OpenXrViewConfiguration::Views() const {
return local_from_view_;
}
void OpenXrViewConfiguration::SetViews(std::vector<XrView> views) {
DCHECK_EQ(views.size(), local_from_view_.size());
local_from_view_ = std::move(views);
}
const std::vector<XrCompositionLayerProjectionView>&
OpenXrViewConfiguration::ProjectionViews() const {
return projection_views_;
}
XrCompositionLayerProjectionView& OpenXrViewConfiguration::GetProjectionView(
uint32_t view_index) {
DCHECK_LT(view_index, projection_views_.size());
return projection_views_[view_index];
}
OpenXrLayers::OpenXrLayers(XrSpace space,
XrEnvironmentBlendMode blend_mode,
const std::vector<XrCompositionLayerProjectionView>&
primary_projection_views)
: space_(space), blend_mode_(blend_mode) {
InitializeLayer(primary_projection_views, primary_projection_layer_);
}
OpenXrLayers::~OpenXrLayers() = default;
void OpenXrLayers::AddSecondaryLayerForType(
XrViewConfigurationType type,
const std::vector<XrCompositionLayerProjectionView>& projection_views) {
secondary_projection_layers_.emplace_back();
InitializeLayer(projection_views, secondary_projection_layers_.back());
secondary_composition_layers_.push_back(
reinterpret_cast<XrCompositionLayerBaseHeader*>(
&secondary_projection_layers_.back()));
secondary_layer_info_.emplace_back();
XrSecondaryViewConfigurationLayerInfoMSFT& layer_info =
secondary_layer_info_.back();
layer_info.type = XR_TYPE_SECONDARY_VIEW_CONFIGURATION_LAYER_INFO_MSFT;
layer_info.viewConfigurationType = type;
layer_info.environmentBlendMode = blend_mode_;
layer_info.layerCount = 1;
layer_info.layers = &secondary_composition_layers_.back();
}
void OpenXrLayers::InitializeLayer(
const std::vector<XrCompositionLayerProjectionView>& projection_views,
XrCompositionLayerProjection& layer) {
layer.type = XR_TYPE_COMPOSITION_LAYER_PROJECTION;
layer.next = nullptr;
layer.layerFlags = 0;
layer.space = space_;
layer.viewCount = projection_views.size();
layer.views = projection_views.data();
if (blend_mode_ == XR_ENVIRONMENT_BLEND_MODE_ALPHA_BLEND) {
layer.layerFlags |= XR_COMPOSITION_LAYER_BLEND_TEXTURE_SOURCE_ALPHA_BIT;
}
}
} // namespace device