summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/modules/xr/xr_depth_manager.cc
blob: 86f8e3b321564a32fe5fc2e54d41eb967df159a8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "third_party/blink/renderer/modules/xr/xr_depth_manager.h"

#include "base/trace_event/trace_event.h"
#include "third_party/blink/renderer/modules/xr/xr_cpu_depth_information.h"
#include "third_party/blink/renderer/modules/xr/xr_session.h"

namespace {

constexpr char kInvalidUsageMode[] =
    "Unable to obtain XRCPUDepthInformation in \"gpu-optimized\" usage mode.";

String UsageToString(device::mojom::XRDepthUsage usage) {
  switch (usage) {
    case device::mojom::XRDepthUsage::kCPUOptimized:
      return "cpu-optimized";
    case device::mojom::XRDepthUsage::kGPUOptimized:
      return "gpu-optimized";
  }
}

String DataFormatToString(device::mojom::XRDepthDataFormat data_format) {
  switch (data_format) {
    case device::mojom::XRDepthDataFormat::kLuminanceAlpha:
      return "luminance-alpha";
    case device::mojom::XRDepthDataFormat::kFloat32:
      return "float32";
  }
}

}  // namespace

namespace blink {

XRDepthManager::XRDepthManager(
    base::PassKey<XRSession> pass_key,
    XRSession* session,
    const device::mojom::blink::XRDepthConfig& depth_configuration)
    : session_(session),
      usage_(depth_configuration.depth_usage),
      data_format_(depth_configuration.depth_data_format),
      usage_str_(UsageToString(usage_)),
      data_format_str_(DataFormatToString(data_format_)) {
  DVLOG(3) << __func__ << ": usage_=" << usage_
           << ", data_format_=" << data_format_;
}

XRDepthManager::~XRDepthManager() = default;

void XRDepthManager::ProcessDepthInformation(
    device::mojom::blink::XRDepthDataPtr depth_data) {
  DVLOG(3) << __func__ << ": depth_data valid? " << !!depth_data;

  // Throw away old data, we won't need it anymore because we'll either replace
  // it with new data, or no new data is available (& we don't want to keep the
  // old data in that case as well).
  depth_data_ = nullptr;
  data_ = nullptr;

  if (depth_data) {
    DVLOG(3) << __func__ << ": depth_data->which()="
             << static_cast<uint32_t>(depth_data->which());

    switch (depth_data->which()) {
      case device::mojom::blink::XRDepthData::Tag::DATA_STILL_VALID:
        // Stale depth buffer is still the most recent information we have.
        // Current API shape is not well-suited to return data pertaining to
        // older frames, so we just discard the data we previously got and will
        // not set the new one.
        break;
      case device::mojom::blink::XRDepthData::Tag::UPDATED_DEPTH_DATA:
        // We got new depth buffer - store the current depth data as a member.
        depth_data_ = std::move(depth_data->get_updated_depth_data());
        break;
    }
  }
}

XRCPUDepthInformation* XRDepthManager::GetCpuDepthInformation(
    const XRFrame* xr_frame,
    ExceptionState& exception_state) {
  DVLOG(2) << __func__;

  if (usage_ != device::mojom::XRDepthUsage::kCPUOptimized) {
    exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
                                      kInvalidUsageMode);
    return nullptr;
  }

  if (!depth_data_) {
    return nullptr;
  }

  EnsureData();

  return MakeGarbageCollected<XRCPUDepthInformation>(
      xr_frame, depth_data_->size, depth_data_->norm_texture_from_norm_view,
      depth_data_->raw_value_to_meters, data_format_, data_);
}

XRWebGLDepthInformation* XRDepthManager::GetWebGLDepthInformation(
    const XRFrame* xr_frame,
    ExceptionState& exception_state) {
  DVLOG(2) << __func__;

  if (usage_ != device::mojom::XRDepthUsage::kGPUOptimized) {
    exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
                                      kInvalidUsageMode);
    return nullptr;
  }

  NOTREACHED();
  return nullptr;
}

void XRDepthManager::EnsureData() {
  DCHECK(depth_data_);

  if (data_) {
    return;
  }

  // Copy the pixel data into ArrayBuffer:
  data_ = DOMArrayBuffer::Create(depth_data_->pixel_data.data(),
                                 depth_data_->pixel_data.size());
}

void XRDepthManager::Trace(Visitor* visitor) const {
  visitor->Trace(session_);
  visitor->Trace(data_);
}

}  // namespace blink