1 //
2 // Copyright 2016 Pixar
3 //
4 // Licensed under the Apache License, Version 2.0 (the "Apache License")
5 // with the following modification; you may not use this file except in
6 // compliance with the Apache License and the following modification to it:
7 // Section 6. Trademarks. is deleted and replaced with:
8 //
9 // 6. Trademarks. This License does not grant permission to use the trade
10 //    names, trademarks, service marks, or product names of the Licensor
11 //    and its affiliates, except as required to comply with Section 4(c) of
12 //    the License and to reproduce the content of the NOTICE file.
13 //
14 // You may obtain a copy of the Apache License at
15 //
16 //     http://www.apache.org/licenses/LICENSE-2.0
17 //
18 // Unless required by applicable law or agreed to in writing, software
19 // distributed under the Apache License with the above modification is
20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21 // KIND, either express or implied. See the Apache License for the specific
22 // language governing permissions and limitations under the Apache License.
23 //
24 #include "pxr/imaging/hd/vtBufferSource.h"
25 #include "pxr/imaging/hd/perfLog.h"
26 
27 #include "pxr/base/vt/array.h"
28 #include "pxr/base/vt/types.h"
29 
30 #include "pxr/base/gf/matrix4d.h"
31 #include "pxr/base/gf/matrix4f.h"
32 
33 #include "pxr/base/tf/getenv.h"
34 #include <iostream>
35 
36 PXR_NAMESPACE_OPEN_SCOPE
37 
38 
39 // ------------------------------------------------------------------------- //
40 // HdVtBufferSource Implementation
41 // ------------------------------------------------------------------------- //
42 
43 void
_SetValue(const VtValue & v,int arraySize)44 HdVtBufferSource::_SetValue(const VtValue &v, int arraySize)
45 {
46     _value = v;
47     _tupleType = HdGetValueTupleType(_value);
48 
49     // XXX: The following is a bit weird and could use reconsideration.
50     // The GL backend has specific alignment requirement for bools.
51     // Currently that is implemented by having HdVtBufferSource promote
52     // bool into int32 values while still reporting the value type as
53     // HdTypeBool (so that shader codegen can emit the right typenames).
54     // It would be better for this kind of concern to be handled closer
55     // to the specific backend.
56     // Array and componented bools are not currently supported.
57     if (_value.IsHolding<bool>()) {
58         int intValue = _value.UncheckedGet<bool>() ? 1 : 0;
59         _value = VtValue(intValue);
60         // Intentionally leave _tupleType as HdTypeBool; see comment above.
61     }
62 
63     // For the common case of a default value that is an empty
64     // VtArray<T>, interpret it as one T per element rather than
65     // a zero-sized tuple.
66     if (_value.IsArrayValued() && _value.GetArraySize() == 0) {
67         _tupleType.count = 1;
68         _numElements = 0;
69         return;
70     }
71 
72     // Factor the VtArray length into numElements and tuple count.
73     // VtArray is a 1D array and does not have multidimensional shape,
74     // therefore it cannot distinguish the case of N values for M elements
75     // from the case of 1 value for NM elements.  This is why
76     // HdVtBufferSource requires the caller to provide this context
77     // via the arraySize argument, so it can apply that shape here.
78     _numElements = _tupleType.count / arraySize;
79     _tupleType.count = arraySize;
80 }
81 
HdVtBufferSource(TfToken const & name,VtValue const & value,int arraySize)82 HdVtBufferSource::HdVtBufferSource(TfToken const& name, VtValue const& value,
83                                    int arraySize)
84     : _name(name)
85 {
86     _SetValue(value, arraySize);
87 }
88 
HdVtBufferSource(TfToken const & name,GfMatrix4d const & matrix)89 HdVtBufferSource::HdVtBufferSource(TfToken const &name,
90                                    GfMatrix4d const &matrix)
91     : _name(name)
92 {
93     if (GetDefaultMatrixType() == HdTypeDoubleMat4) {
94         _SetValue( VtValue(matrix), 1 );
95     } else {
96         GfMatrix4f fmatrix(
97             matrix[0][0], matrix[0][1], matrix[0][2], matrix[0][3],
98             matrix[1][0], matrix[1][1], matrix[1][2], matrix[1][3],
99             matrix[2][0], matrix[2][1], matrix[2][2], matrix[2][3],
100             matrix[3][0], matrix[3][1], matrix[3][2], matrix[3][3]);
101         _SetValue( VtValue(fmatrix), 1 );
102     }
103 }
104 
HdVtBufferSource(TfToken const & name,VtArray<GfMatrix4d> const & matrices,int arraySize)105 HdVtBufferSource::HdVtBufferSource(TfToken const &name,
106                                    VtArray<GfMatrix4d> const &matrices,
107                                    int arraySize)
108     : _name(name)
109 {
110     if (GetDefaultMatrixType() == HdTypeDoubleMat4) {
111         _SetValue( VtValue(matrices), arraySize );
112     } else {
113         VtArray<GfMatrix4f> fmatrices(matrices.size());
114         for (size_t i = 0; i < matrices.size(); ++i) {
115             GfMatrix4d const &matrix = matrices[i];
116             GfMatrix4f fmatrix(
117                 matrix[0][0], matrix[0][1], matrix[0][2], matrix[0][3],
118                 matrix[1][0], matrix[1][1], matrix[1][2], matrix[1][3],
119                 matrix[2][0], matrix[2][1], matrix[2][2], matrix[2][3],
120                 matrix[3][0], matrix[3][1], matrix[3][2], matrix[3][3]);
121             fmatrices[i] = fmatrix;
122         }
123         _SetValue( VtValue(fmatrices), arraySize );
124     }
125 }
126 
~HdVtBufferSource()127 HdVtBufferSource::~HdVtBufferSource()
128 {
129 }
130 
131 void
Truncate(size_t numElements)132 HdVtBufferSource::Truncate(size_t numElements)
133 {
134     if (numElements > _numElements) {
135         TF_CODING_ERROR(
136             "Buffer '%s', cannot truncate from length %zu to length %zu",
137             _name.GetText(), _numElements, numElements);
138         return;
139     }
140 
141     _numElements = numElements;
142 }
143 
144 /*static*/
145 HdType
GetDefaultMatrixType()146 HdVtBufferSource::GetDefaultMatrixType()
147 {
148     static HdType matrixType =
149         TfGetenvBool("HD_ENABLE_DOUBLE_MATRIX", false)
150         ? HdTypeDoubleMat4 : HdTypeFloatMat4;
151     return matrixType;
152 }
153 
154 /*virtual*/
155 size_t
GetNumElements() const156 HdVtBufferSource::GetNumElements() const
157 {
158     return _numElements;
159 }
160 
161 bool
_CheckValid() const162 HdVtBufferSource::_CheckValid() const
163 {
164     return _tupleType.type != HdTypeInvalid;
165 }
166 
167 HD_API
operator <<(std::ostream & out,const HdVtBufferSource & self)168 std::ostream &operator <<(std::ostream &out, const HdVtBufferSource& self) {
169     const HdTupleType t = self.GetTupleType();
170 
171     out << "Buffer Source:\n";
172     out << "    Name:      " << self.GetName() << "\n";
173     out << "    Size:      " << HdDataSizeOfTupleType(t) << "\n";
174     out << "    Type:      " << TfEnum::GetName(t.type) << "\n";
175     out << "    Count:     " << t.count << "\n";
176     out << "    Num elems: " << self.GetNumElements() << "\n";
177     return out;
178 }
179 
180 PXR_NAMESPACE_CLOSE_SCOPE
181 
182