54 using gfx::AttributeArray;
56 using gfx::CubeMapTexture;
58 using gfx::BufferObject;
59 using gfx::BufferObjectElement;
63 using gfx::IndexBuffer;
69 using gfx::ShaderInputRegistry;
71 using gfx::ShaderProgram;
75 using gfx::StateTable;
78 using gfx::TextureBase;
81 using gfx::UniformBlock;
93 explicit Mask(uint32 value_in) :
value(value_in) {}
97 std::ostream&
operator<<(std::ostream& out,
const Mask& mask) {
98 return out <<
"0x" << std::hex << mask.value << std::dec;
110 explicit Pointer(
const void* pointer_in) :
pointer(pointer_in) {}
114 std::ostream&
operator<<(std::ostream& out,
const Pointer& p) {
135 template <
int Dimension,
typename T>
136 const std::string
ValueToString(
const math::VectorBase<Dimension, T>& vec) {
138 static_cast<const math::Vector<Dimension, T>&
>(vec));
148 template<
typename ValueType,
typename ValuePr
intType>
149 static void PrintBufferData(std::ostream& out,
150 const char* data,
const size_t num_components) {
151 if (
const ValueType* typed_data = reinterpret_cast<const ValueType*>(data)) {
152 if (num_components == 1) {
153 out << static_cast<ValuePrintType>(typed_data[0]);
156 for (
size_t i = 0; i < num_components; ++i) {
157 out << static_cast<ValuePrintType>(typed_data[i]);
158 if (i < num_components - 1)
170 static void PrintMatrixBufferData(std::ostream& out,
172 const size_t num_columns,
173 const size_t num_components) {
174 if (
const T* typed_data = reinterpret_cast<const T*>(data)) {
176 for (
size_t i = 0; i < num_components; ++i) {
177 for (
size_t j = 0; j < num_columns; ++j) {
178 out << typed_data[i * num_columns + j];
179 if (j < num_columns - 1)
182 if (i < num_components - 1)
189 static void PrintBufferDataByType(std::ostream& out,
190 BufferObject::ComponentType
type,
191 const char* ptr,
size_t count) {
193 case BufferObject::kByte:
194 PrintBufferData<int8, int32>(out, ptr, count);
196 case BufferObject::kUnsignedByte:
197 PrintBufferData<uint8, uint32>(out, ptr, count);
199 case BufferObject::kShort:
200 PrintBufferData<int16, int32>(out, ptr, count);
202 case BufferObject::kUnsignedShort:
203 PrintBufferData<uint16, uint32>(out, ptr, count);
205 case BufferObject::kInt:
206 PrintBufferData<int32, int32>(out, ptr, count);
208 case BufferObject::kUnsignedInt:
209 PrintBufferData<uint32, uint32>(out, ptr, count);
211 case BufferObject::kFloat:
212 PrintBufferData<float, float>(out, ptr, count);
214 case BufferObject::kFloatMatrixColumn2:
215 PrintMatrixBufferData<float>(out, ptr, 2U, count);
217 case BufferObject::kFloatMatrixColumn3:
218 PrintMatrixBufferData<float>(out, ptr, 3U, count);
220 case BufferObject::kFloatMatrixColumn4:
221 PrintMatrixBufferData<float>(out, ptr, 4U, count);
223 case BufferObject::kInvalid:
225 #if !defined(ION_COVERAGE) // COV_NF_START
226 DCHECK(
false) <<
"Invalid buffer component type " <<
type;
234 static size_t GetBufferAttributeVertexCount(
const AttributeArray& aa) {
235 size_t min_vertex_count = 0;
236 bool is_first =
true;
237 const size_t attribute_count = aa.GetAttributeCount();
238 for (
size_t i = 0; i < attribute_count; ++i) {
239 const Attribute& attribute = aa.GetAttribute(i);
240 if (attribute.IsValid() && attribute.Is<BufferObjectElement>() &&
241 aa.IsAttributeEnabled(i)) {
243 attribute.GetValue<BufferObjectElement>().buffer_object->GetCount();
248 min_vertex_count = std::min(min_vertex_count, vertex_count);
252 return min_vertex_count;
255 static const std::string GetBufferAttributeValue(
const AttributeArray& aa,
256 size_t vertex_index) {
257 std::ostringstream s;
258 bool is_first =
true;
259 const size_t attribute_count = aa.GetAttributeCount();
260 for (
size_t i = 0; i < attribute_count; ++i) {
261 const Attribute& a = aa.GetAttribute(i);
262 if (a.IsValid() && a.Is<BufferObjectElement>() &&
263 aa.IsAttributeEnabled(i)) {
272 a.GetValue<BufferObjectElement>().buffer_object;
273 const size_t num_entries = bo->GetCount();
274 if (vertex_index < num_entries) {
277 const size_t stride = bo->GetStructSize();
278 const char* raw_data =
279 static_cast<const char*
>(bo->GetData()->GetData());
281 const size_t spec_index = a.GetValue<BufferObjectElement>().spec_index;
282 const BufferObject::Spec& spec = bo->GetSpec(spec_index);
285 raw_data ? &raw_data[stride * vertex_index + spec.byte_offset]
287 PrintBufferDataByType(s, spec.type, ptr, spec.component_count);
307 class Table :
public base::Array2<std::string> {
309 Table(
size_t num_columns,
size_t num_rows,
bool has_label_column)
310 : base::Array2<std::string>(num_columns, num_rows),
322 StringField(
const std::string& name_in,
const std::string& value_in)
330 TableField(
const std::string& name_in,
const Table& table_in)
339 ObjectField(
const std::string& name_in,
size_t object_index_in)
348 Object(
const void* pointer_in,
const std::string& type_in,
349 const std::string& label_in,
bool is_inside_field_in)
368 size_t BeginObject(
const void*
pointer,
const std::string& type,
371 all_objects_.push_back(Object(pointer, type, label, is_inside_field));
375 if (!is_inside_field) {
379 GetCurObject()->child_object_indices.push_back(index);
387 template <
typename T>
388 size_t BeginLabeledObject(
const T* pointer,
const std::string& type) {
389 return BeginObject(pointer, type, pointer ? pointer->GetLabel() :
"");
399 template <
typename T>
400 void AddField(
const std::string&
name,
const T& value) {
406 template <
typename E>
407 void AddEnumField(
const std::string& name, E enumvalue) {
411 void AddStringField(
const std::string& name,
const std::string& value) {
412 GetCurObject()->string_fields.push_back(StringField(name, value));
415 void AddTableField(
const std::string& name,
const Table&
table) {
416 GetCurObject()->table_fields.push_back(TableField(name, table));
419 void AddObjectField(
const std::string& name,
size_t object_index) {
420 GetCurObject()->object_fields.push_back(ObjectField(name, object_index));
423 const std::vector<size_t>& GetRootObjectIndices()
const {
427 const Object& GetObject(
size_t index)
const {
433 Object* GetCurObject() {
457 template <
typename T>
458 MultiField& Add(
const std::string& name,
const T& value) {
463 template <
typename E>
464 MultiField& AddEnum(
const std::string& name, E enumvalue) {
469 MultiField& AddString(
const std::string& name,
const std::string& value) {
470 return AddField(name, value);
474 template <
typename T>
475 MultiField& AddIf(
bool cond,
const std::string& name,
const T& value) {
483 const std::string Get()
const {
return out_.str(); }
486 MultiField& AddField(
const std::string& name,
const std::string& value) {
508 template <
int Dimension,
typename T>
509 static const Tree::Table BuildMatrixTable(
const math::Matrix<Dimension, T>& m) {
510 Tree::Table
table(Dimension, Dimension,
false);
511 for (
int row = 0; row < Dimension; ++row) {
512 for (
int col = 0; col < Dimension; ++col) {
520 static const Tree::Table GetIndexBufferTable(
521 const IndexBuffer& ib,
const BufferObject::Spec& spec) {
523 const size_t stride = ib.GetStructSize();
524 const char* raw_data = ib.GetData().Get() ?
525 static_cast<const char*
>(ib.GetData()->GetData()) :
527 const size_t index_count = ib.GetCount();
530 static const size_t kNumColumns = 10U;
531 const size_t num_rows = (index_count + kNumColumns - 1) / kNumColumns;
532 Tree::Table
table(1U + kNumColumns, num_rows,
true);
533 size_t cur_index = 0;
534 for (
size_t row = 0; row < num_rows; ++row) {
536 const size_t last = std::min(cur_index + kNumColumns - 1, index_count - 1);
541 std::ostringstream out;
542 for (
size_t col = 0; col < kNumColumns; ++col) {
544 raw_data ? &raw_data[stride * cur_index + spec.byte_offset] : NULL;
545 PrintBufferDataByType(out, spec.type, ptr, spec.component_count);
546 table.Set(1U + col, row, out.str());
548 if (++cur_index >= index_count)
565 TreeBuilder(
bool address_printing_enabled,
566 bool full_shape_printing_enabled)
571 const Tree& BuildTree(
const Node& node) {
578 class ScopedObjectBase {
580 ScopedObjectBase(Tree* tree,
const void*
object,
const std::string& type,
581 const std::string& label,
bool is_inside_field)
584 tree_->BeginObject(object, type, label, is_inside_field)) {}
585 ~ScopedObjectBase() {
tree_->EndObject(); }
594 template <
typename T>
class ScopedLabeledObject :
public ScopedObjectBase {
596 ScopedLabeledObject(Tree* tree,
const T*
object,
const std::string& type,
597 bool is_inside_field)
598 : ScopedObjectBase(tree,
object, type,
599 object ? object->GetLabel() : std::string(
""),
604 class ScopedObject :
public ScopedObjectBase {
606 ScopedObject(Tree* tree,
const void*
object,
const std::string& type)
607 : ScopedObjectBase(tree, object, type,
"", false) {}
612 class ContainerObject :
public ScopedObjectBase {
615 explicit ContainerObject(Tree* tree)
616 : ScopedObjectBase(tree, NULL,
"",
"", true) {}
622 void AddNode(
const Node& node);
623 void AddStateTable(
const StateTable& st);
624 void AddImageFields(
const Image&
image,
const char* face);
625 size_t AddCubeMapTexture(
const CubeMapTexture*
texture);
626 size_t AddTexture(
const Texture*
texture);
627 void AddTextureBaseFields(
const TextureBase*
texture);
628 size_t AddSampler(
const Sampler* sampler);
629 void AddShape(
const Shape& shape);
630 void AddUniform(
const Uniform& uniform);
631 void AddUniformBlock(
const UniformBlock* block);
632 void AddUniformValueField(
const Uniform& uniform);
633 void AddAttributeArray(
const AttributeArray& va,
bool add_contents);
634 void AddAttribute(
const Attribute& attribute,
bool is_enabled);
635 void AddNonbufferAttributeValueField(
const Attribute& attribute);
636 void AddBufferAttributeValues(
const AttributeArray& aa);
644 void TreeBuilder::AddNode(
const Node& node) {
645 ScopedLabeledObject<Node> obj(&
tree_, &node,
"Node",
false);
647 tree_.AddField(
"Enabled", node.IsEnabled());
650 if (
const ShaderProgram* program = node.GetShaderProgram().Get())
651 tree_.AddField(
"Shader ID", program->GetLabel());
654 if (
const StateTable* st = node.GetStateTable().Get())
658 const base::AllocVector<Uniform>& uniforms = node.GetUniforms();
659 for (
size_t i = 0; i < uniforms.size(); ++i)
660 AddUniform(uniforms[i]);
663 const base::AllocVector<UniformBlockPtr>& uniform_blocks =
664 node.GetUniformBlocks();
665 for (
size_t i = 0; i < uniform_blocks.size(); ++i)
666 AddUniformBlock(uniform_blocks[i].Get());
669 const base::AllocVector<ShapePtr>& shapes = node.GetShapes();
670 for (
size_t i = 0; i < shapes.size(); ++i)
671 AddShape(*shapes[i]);
674 const base::AllocVector<NodePtr>& children = node.GetChildren();
675 for (
size_t i = 0; i < children.size(); ++i)
676 AddNode(*children[i]);
679 void TreeBuilder::AddStateTable(
const StateTable& st) {
680 ScopedObject obj(&
tree_, &st,
"StateTable");
683 const int num_capabilities = StateTable::GetCapabilityCount();
684 for (
int i = 0; i < num_capabilities; ++i) {
685 const StateTable::Capability cap =
static_cast<StateTable::Capability
>(i);
686 if (st.IsCapabilitySet(cap))
687 tree_.AddField(StateTable::GetEnumString(cap), st.IsEnabled(cap));
691 if (st.IsValueSet(StateTable::kBlendColorValue))
692 tree_.AddField(
"Blend Color", st.GetBlendColor());
693 if (st.IsValueSet(StateTable::kBlendEquationsValue)) {
694 tree_.AddStringField(
697 .AddEnum(
"RGB", st.GetRgbBlendEquation())
698 .AddEnum(
"Alpha", st.GetAlphaBlendEquation())
701 if (st.IsValueSet(StateTable::kBlendFunctionsValue)) {
702 tree_.AddStringField(
705 .AddEnum(
"RGB-src", st.GetRgbBlendFunctionSourceFactor())
706 .AddEnum(
"RGB-dest", st.GetRgbBlendFunctionDestinationFactor())
707 .AddEnum(
"Alpha-src", st.GetAlphaBlendFunctionSourceFactor())
708 .AddEnum(
"Alpha-dest", st.GetAlphaBlendFunctionDestinationFactor())
711 if (st.IsValueSet(StateTable::kClearColorValue))
712 tree_.AddField(
"Clear Color", st.GetClearColor());
713 if (st.IsValueSet(StateTable::kColorWriteMasksValue)) {
714 tree_.AddStringField(
717 .Add(
"R", st.GetRedColorWriteMask())
718 .Add(
"G", st.GetGreenColorWriteMask())
719 .Add(
"B", st.GetBlueColorWriteMask())
720 .Add(
"A", st.GetAlphaColorWriteMask())
723 if (st.IsValueSet(StateTable::kCullFaceModeValue))
724 tree_.AddEnumField(
"Cull Face Mode", st.GetCullFaceMode());
725 if (st.IsValueSet(StateTable::kFrontFaceModeValue))
726 tree_.AddEnumField(
"Front Face Mode", st.GetFrontFaceMode());
727 if (st.IsValueSet(StateTable::kClearDepthValue))
728 tree_.AddField(
"Clear Depth Value", st.GetClearDepthValue());
729 if (st.IsValueSet(StateTable::kDepthFunctionValue))
730 tree_.AddEnumField(
"Depth Function", st.GetDepthFunction());
731 if (st.IsValueSet(StateTable::kDepthRangeValue))
732 tree_.AddField(
"Depth Range", st.GetDepthRange());
733 if (st.IsValueSet(StateTable::kDepthWriteMaskValue))
734 tree_.AddField(
"Depth Write Mask", st.GetDepthWriteMask());
735 if (st.IsValueSet(StateTable::kDrawBufferValue))
736 tree_.AddEnumField(
"Draw Buffer", st.GetDrawBuffer());
737 if (st.IsValueSet(StateTable::kHintsValue))
738 tree_.AddEnumField(
"Generate Mipmap Hint",
739 st.GetHint(StateTable::kGenerateMipmapHint));
740 if (st.IsValueSet(StateTable::kLineWidthValue))
741 tree_.AddField(
"Line Width", st.GetLineWidth());
742 if (st.IsValueSet(StateTable::kPolygonOffsetValue)) {
743 tree_.AddStringField(
746 .Add(
"Factor", st.GetPolygonOffsetFactor())
747 .Add(
"Units", st.GetPolygonOffsetUnits())
750 if (st.IsValueSet(StateTable::kSampleCoverageValue)) {
751 tree_.AddStringField(
754 .Add(
"Value", st.GetSampleCoverageValue())
755 .Add(
"Inverted", st.IsSampleCoverageInverted())
758 if (st.IsValueSet(StateTable::kScissorBoxValue))
759 tree_.AddField(
"Scissor Box", st.GetScissorBox());
760 if (st.IsValueSet(StateTable::kStencilFunctionsValue)) {
761 tree_.AddStringField(
764 .AddEnum(
"FFunc", st.GetFrontStencilFunction())
765 .Add(
"FRef", st.GetFrontStencilReferenceValue())
766 .Add(
"FMask", Mask(st.GetFrontStencilMask()))
767 .AddEnum(
"BFunc", st.GetBackStencilFunction())
768 .Add(
"BRef", st.GetBackStencilReferenceValue())
769 .Add(
"BMask", Mask(st.GetBackStencilMask()))
772 if (st.IsValueSet(StateTable::kStencilOperationsValue)) {
773 tree_.AddStringField(
774 "Stencil Operations",
776 .AddEnum(
"FFail", st.GetFrontStencilFailOperation())
777 .AddEnum(
"FDFail", st.GetFrontStencilDepthFailOperation())
778 .AddEnum(
"FPass", st.GetFrontStencilPassOperation())
779 .AddEnum(
"BFail", st.GetBackStencilFailOperation())
780 .AddEnum(
"BDFail", st.GetBackStencilDepthFailOperation())
781 .AddEnum(
"BPass", st.GetBackStencilPassOperation())
784 if (st.IsValueSet(StateTable::kClearStencilValue))
785 tree_.AddField(
"Clear Stencil Value", st.GetClearStencilValue());
786 if (st.IsValueSet(StateTable::kStencilWriteMasksValue)) {
787 tree_.AddStringField(
788 "Stencil Write Masks",
790 .Add(
"F", Mask(st.GetFrontStencilWriteMask()))
791 .Add(
"B", Mask(st.GetBackStencilWriteMask()))
794 if (st.IsValueSet(StateTable::kViewportValue))
795 tree_.AddField(
"Viewport", st.GetViewport());
798 void TreeBuilder::AddImageFields(
const Image&
image,
const char* face) {
799 tree_.AddStringField(
803 .AddString(
"Face", face)
804 .AddString(
"Format", Image::GetFormatString(image.GetFormat()))
805 .Add(
"Width", image.GetWidth())
806 .Add(
"Height", image.GetHeight())
807 .Add(
"Depth", image.GetDepth())
808 .AddEnum(
"Type", image.GetType())
809 .AddEnum(
"Dimensions", image.GetDimensions())
813 size_t TreeBuilder::AddCubeMapTexture(
const CubeMapTexture*
texture) {
814 ScopedLabeledObject<CubeMapTexture> cmt(
815 &
tree_, texture,
"CubeMapTexture",
true);
817 for (
int i = 0; i < 6; ++i) {
818 const CubeMapTexture::CubeFace face =
819 static_cast<CubeMapTexture::CubeFace
>(i);
820 if (texture->HasImage(face, 0U)) {
821 const Image& image = *texture->GetImage(face, 0U);
825 AddTextureBaseFields(texture);
827 return cmt.GetIndex();
830 size_t TreeBuilder::AddTexture(
const Texture* texture) {
831 ScopedLabeledObject<Texture> t(&
tree_, texture,
"Texture",
true);
833 if (texture->HasImage(0U)) {
834 const Image& image = *texture->GetImage(0U);
835 AddImageFields(image,
"None");
837 AddTextureBaseFields(texture);
842 void TreeBuilder::AddTextureBaseFields(
const TextureBase* texture) {
845 math::Range1i(texture->GetBaseLevel(), texture->GetMaxLevel()));
846 tree_.AddStringField(
849 .Add(
"Samples", texture->GetMultisampleSamples())
850 .Add(
"Fixed sample locations",
851 texture->IsMultisampleFixedSampleLocations())
853 tree_.AddStringField(
856 .AddEnum(
"R", texture->GetSwizzleRed())
857 .AddEnum(
"G", texture->GetSwizzleGreen())
858 .AddEnum(
"B", texture->GetSwizzleBlue())
859 .AddEnum(
"A", texture->GetSwizzleAlpha())
861 tree_.AddObjectField(
"Sampler", AddSampler(texture->GetSampler().Get()));
864 size_t TreeBuilder::AddSampler(
const Sampler* sampler) {
865 ScopedLabeledObject<Sampler> s(&
tree_, sampler,
"Sampler",
true);
867 tree_.AddField(
"Autogenerating mipmaps",
868 sampler->IsAutogenerateMipmapsEnabled());
869 tree_.AddEnumField(
"Texture compare mode", sampler->GetCompareMode());
870 tree_.AddEnumField(
"Texture compare function",
871 sampler->GetCompareFunction());
872 tree_.AddEnumField(
"MinFilter mode", sampler->GetMinFilter());
873 tree_.AddEnumField(
"MagFilter mode", sampler->GetMagFilter());
874 tree_.AddField(
"Level-of-detail range",
876 tree_.AddStringField(
879 .AddEnum(
"R", sampler->GetWrapR())
880 .AddEnum(
"S", sampler->GetWrapS())
881 .AddEnum(
"T", sampler->GetWrapT())
887 void TreeBuilder::AddShape(
const Shape& shape) {
888 ScopedLabeledObject<Shape> s(&
tree_, &shape,
"Shape",
false);
890 tree_.AddEnumField(
"Primitive Type", shape.GetPrimitiveType());
892 if (
const AttributeArray* aa = shape.GetAttributeArray().Get()) {
894 AddAttributeArray(*aa, !was_added);
899 if (
const size_t range_count = shape.GetVertexRangeCount()) {
900 tree_.AddField(
"# Vertex Ranges", range_count);
901 for (
size_t i = 0; i < range_count; ++i) {
902 tree_.AddStringField(
905 .Add(
"Enabled", shape.IsVertexRangeEnabled(i))
906 .Add(
"Range", shape.GetVertexRange(i))
911 if (IndexBuffer* ib = shape.GetIndexBuffer().Get()) {
912 ScopedLabeledObject<IndexBuffer> si(&
tree_, ib,
"IndexBuffer",
false);
916 const BufferObject::Spec& spec = ib->GetSpec(0);
918 tree_.AddEnumField(
"Type", spec.type);
919 tree_.AddEnumField(
"Target", ib->GetTarget());
920 tree_.AddTableField(
"Indices", GetIndexBufferTable(*ib, spec));
925 void TreeBuilder::AddUniform(
const Uniform& uniform) {
926 DCHECK(uniform.IsValid());
927 ScopedObject u(&
tree_, &uniform,
"Uniform");
929 const ShaderInputRegistry::Spec<Uniform>& spec =
930 *uniform.GetRegistry().GetSpec(uniform);
931 tree_.AddField(
"Name", spec.name);
932 tree_.AddStringField(
"Type", Uniform::GetValueTypeName(spec.value_type));
933 AddUniformValueField(uniform);
936 void TreeBuilder::AddUniformBlock(
const UniformBlock* block) {
937 ScopedLabeledObject<UniformBlock> u(&
tree_, block,
"UniformBlock",
false);
939 const base::AllocVector<Uniform>& uniforms = block->GetUniforms();
940 tree_.AddField(
"Enabled", block->IsEnabled());
941 for (
size_t i = 0; i < uniforms.size(); ++i)
942 AddUniform(uniforms[i]);
946 void TreeBuilder::AddUniformValueField(
const Uniform& uniform) {
947 DCHECK(uniform.IsValid());
948 const std::string&
name(
"Value");
949 switch (uniform.GetType()) {
951 if (uniform.GetCount()) {
952 for (
size_t i = 0; i < uniform.GetCount(); ++i)
954 uniform.GetValueAt<
float>(i));
956 tree_.AddField(name, uniform.GetValue<
float>());
960 if (uniform.GetCount()) {
961 for (
size_t i = 0; i < uniform.GetCount(); ++i)
963 uniform.GetValueAt<
int>(i));
965 tree_.AddField(name, uniform.GetValue<
int>());
969 if (uniform.GetCount()) {
970 for (
size_t i = 0; i < uniform.GetCount(); ++i)
972 uniform.GetValueAt<uint32>(i));
974 tree_.AddField(name, uniform.GetValue<uint32>());
978 if (uniform.GetCount()) {
979 for (
size_t i = 0; i < uniform.GetCount(); ++i) {
980 tree_.AddObjectField(
986 tree_.AddObjectField(
992 if (uniform.GetCount()) {
993 for (
size_t i = 0; i < uniform.GetCount(); ++i) {
994 tree_.AddObjectField(
996 AddTexture(uniform.GetValueAt<
TexturePtr>(i).Get()));
999 tree_.AddObjectField(name,
1000 AddTexture(uniform.GetValue<
TexturePtr>().Get()));
1004 if (uniform.GetCount()) {
1005 for (
size_t i = 0; i < uniform.GetCount(); ++i)
1007 uniform.GetValueAt<math::VectorBase2f>(i));
1009 tree_.AddField(name, uniform.GetValue<math::VectorBase2f>());
1013 if (uniform.GetCount()) {
1014 for (
size_t i = 0; i < uniform.GetCount(); ++i)
1016 uniform.GetValueAt<math::VectorBase3f>(i));
1018 tree_.AddField(name, uniform.GetValue<math::VectorBase3f>());
1022 if (uniform.GetCount()) {
1023 for (
size_t i = 0; i < uniform.GetCount(); ++i)
1025 uniform.GetValueAt<math::VectorBase4f>(i));
1027 tree_.AddField(name, uniform.GetValue<math::VectorBase4f>());
1031 if (uniform.GetCount()) {
1032 for (
size_t i = 0; i < uniform.GetCount(); ++i)
1034 uniform.GetValueAt<math::VectorBase2i>(i));
1036 tree_.AddField(name, uniform.GetValue<math::VectorBase2i>());
1040 if (uniform.GetCount()) {
1041 for (
size_t i = 0; i < uniform.GetCount(); ++i)
1043 uniform.GetValueAt<math::VectorBase3i>(i));
1045 tree_.AddField(name, uniform.GetValue<math::VectorBase3i>());
1049 if (uniform.GetCount()) {
1050 for (
size_t i = 0; i < uniform.GetCount(); ++i)
1052 uniform.GetValueAt<math::VectorBase4i>(i));
1054 tree_.AddField(name, uniform.GetValue<math::VectorBase4i>());
1058 if (uniform.GetCount()) {
1059 for (
size_t i = 0; i < uniform.GetCount(); ++i)
1061 uniform.GetValueAt<math::VectorBase2ui>(i));
1063 tree_.AddField(name, uniform.GetValue<math::VectorBase2ui>());
1067 if (uniform.GetCount()) {
1068 for (
size_t i = 0; i < uniform.GetCount(); ++i)
1070 uniform.GetValueAt<math::VectorBase3ui>(i));
1072 tree_.AddField(name, uniform.GetValue<math::VectorBase3ui>());
1076 if (uniform.GetCount()) {
1077 for (
size_t i = 0; i < uniform.GetCount(); ++i)
1079 uniform.GetValueAt<math::VectorBase4ui>(i));
1081 tree_.AddField(name, uniform.GetValue<math::VectorBase4ui>());
1085 if (uniform.GetCount()) {
1086 for (
size_t i = 0; i < uniform.GetCount(); ++i)
1087 tree_.AddTableField(
1091 tree_.AddTableField(
1096 if (uniform.GetCount()) {
1097 for (
size_t i = 0; i < uniform.GetCount(); ++i)
1098 tree_.AddTableField(
1102 tree_.AddTableField(
1107 if (uniform.GetCount()) {
1108 for (
size_t i = 0; i < uniform.GetCount(); ++i)
1109 tree_.AddTableField(
1113 tree_.AddTableField(
1117 #if !defined(ION_COVERAGE) // COV_NF_START
1119 DCHECK(
false) <<
"Invalid uniform type " << uniform.GetType();
1121 #endif // COV_NF_END
1125 void TreeBuilder::AddAttributeArray(
const AttributeArray& aa,
1126 bool add_contents) {
1127 ScopedLabeledObject<AttributeArray> a(&
tree_, &aa,
"AttributeArray",
false);
1128 const size_t attribute_count = aa.GetAttributeCount();
1129 if (add_contents && attribute_count) {
1131 for (
size_t i = 0; i < attribute_count; ++i) {
1132 const Attribute& attribute = aa.GetAttribute(i);
1133 if (attribute.IsValid() && !attribute.Is<BufferObjectElement>())
1134 AddAttribute(attribute, aa.IsAttributeEnabled(i));
1138 for (
size_t i = 0; i < attribute_count; ++i) {
1139 const Attribute& attribute = aa.GetAttribute(i);
1140 if (attribute.IsValid() && attribute.Is<BufferObjectElement>())
1141 AddAttribute(attribute, aa.IsAttributeEnabled(i));
1146 AddBufferAttributeValues(aa);
1150 void TreeBuilder::AddAttribute(
const Attribute& attribute,
bool is_enabled) {
1151 DCHECK(attribute.IsValid());
1152 const bool is_buffer_attribute = attribute.Is<BufferObjectElement>();
1153 const std::string type_name(is_buffer_attribute ?
"(Buffer)" :
"(Nonbuffer)");
1155 ScopedObject a(&
tree_, &attribute, std::string(
"Attribute ") + type_name);
1157 const ShaderInputRegistry::Spec<Attribute>& spec =
1158 *attribute.GetRegistry().GetSpec(attribute);
1159 tree_.AddField(
"Name", spec.name);
1160 tree_.AddField(
"Enabled", is_enabled);
1161 if (is_buffer_attribute) {
1162 tree_.AddField(
"Normalized", attribute.IsFixedPointNormalized());
1166 attribute.GetValue<BufferObjectElement>().buffer_object;
1167 const std::string& label = vb->GetLabel();
1169 tree_.AddField(
"Buffer", label);
1174 AddNonbufferAttributeValueField(attribute);
1178 void TreeBuilder::AddNonbufferAttributeValueField(
const Attribute& attribute) {
1179 DCHECK(attribute.IsValid());
1180 const std::string&
name(
"Value");
1181 switch (attribute.GetType()) {
1183 tree_.AddField(name, attribute.GetValue<
float>());
1186 tree_.AddField(name, attribute.GetValue<math::VectorBase2f>());
1189 tree_.AddField(name, attribute.GetValue<math::VectorBase3f>());
1192 tree_.AddField(name, attribute.GetValue<math::VectorBase4f>());
1195 tree_.AddTableField(
1199 tree_.AddTableField(
1203 tree_.AddTableField(
1207 #if !defined(ION_COVERAGE) // COV_NF_START
1208 DCHECK(
false) <<
"Invalid nonbuffer attribute type "
1209 << attribute.GetType();
1210 #endif // COV_NF_END
1215 void TreeBuilder::AddBufferAttributeValues(
const AttributeArray& aa) {
1216 if (
const size_t vertex_count = GetBufferAttributeVertexCount(aa)) {
1219 ContainerObject co(&
tree_);
1222 GetBufferAttributeValue(aa, i));
1224 object_index = co.GetIndex();
1226 tree_.AddObjectField(
"Buffer Values", object_index);
1238 class TextTreePrinter {
1240 TextTreePrinter(std::ostream& out,
const Tree& tree,
1241 bool address_printing_enabled)
1249 void PrintObject(
size_t object_index);
1250 void PrintObjectHeader(
const Tree::Object&
object);
1251 void PrintObjectField(
const Tree::ObjectField& field);
1252 void PrintStringField(
const Tree::StringField& field);
1253 void PrintTableField(
const Tree::TableField& field);
1254 void PrintLabeledTable(
const Tree::Table& table,
size_t extra_indent);
1255 void PrintUnlabeledTable(
const Tree::Table& table,
size_t extra_indent);
1258 void Indent() { IndentExtra(0); }
1261 void IndentExtra(
size_t extra) {
1263 for (
size_t i = 0; i < num_spaces; ++i)
1273 void TextTreePrinter::Print() {
1274 const std::vector<size_t>& roots =
tree_.GetRootObjectIndices();
1275 for (
size_t i = 0; i < roots.size(); ++i)
1276 PrintObject(roots[i]);
1279 void TextTreePrinter::PrintObject(
size_t object_index) {
1280 const Tree::Object&
object =
tree_.GetObject(object_index);
1283 PrintObjectHeader(
object);
1287 for (
size_t i = 0; i <
object.string_fields.size(); ++i)
1289 for (
size_t i = 0; i <
object.table_fields.size(); ++i)
1291 for (
size_t i = 0; i <
object.object_fields.size(); ++i)
1295 for (
size_t i = 0; i <
object.child_object_indices.size(); ++i)
1304 void TextTreePrinter::PrintObjectHeader(
const Tree::Object&
object) {
1305 if (!
object.is_inside_field)
1310 if (!
object.type.empty()) {
1311 out_ <<
"ION " <<
object.type <<
' ';
1312 if (!
object.label.empty())
1313 out_ <<
"\"" <<
object.label <<
"\" ";
1315 out_ <<
'[' << Pointer(
object.pointer) <<
"] ";
1320 void TextTreePrinter::PrintObjectField(
const Tree::ObjectField& field) {
1322 out_ << field.name <<
": ";
1323 PrintObject(field.object_index);
1326 void TextTreePrinter::PrintStringField(
const Tree::StringField& field) {
1328 out_ << field.name <<
": " << field.value <<
"\n";
1331 void TextTreePrinter::PrintTableField(
const Tree::TableField& field) {
1333 out_ << field.name <<
": ";
1334 const size_t extra_indent = field.name.size() + 3U;
1336 const Tree::Table& table = field.table;
1338 if (table.GetSize()) {
1339 if (table.HasLabelColumn())
1340 PrintLabeledTable(table, extra_indent);
1342 PrintUnlabeledTable(table, extra_indent);
1347 void TextTreePrinter::PrintLabeledTable(
const Tree::Table& table,
1348 size_t extra_indent) {
1349 const size_t num_rows = table.GetHeight();
1350 const size_t num_columns = table.GetWidth();
1351 for (
size_t row = 0; row < num_rows; ++row) {
1354 IndentExtra(extra_indent);
1356 for (
size_t col = 0; col < num_columns; ++col) {
1357 const std::string& cell = table.Get(col, row);
1359 out_ << cell <<
": ";
1360 }
else if (!cell.empty()) {
1369 void TextTreePrinter::PrintUnlabeledTable(
const Tree::Table& table,
1370 size_t extra_indent) {
1371 const size_t num_rows = table.GetHeight();
1372 const size_t num_columns = table.GetWidth();
1373 for (
size_t row = 0; row < num_rows; ++row) {
1378 IndentExtra(extra_indent);
1381 for (
size_t col = 0; col < num_columns; ++col) {
1384 out_ << table.Get(col, row);
1398 class HtmlTreePrinter {
1400 HtmlTreePrinter(std::ostream& out,
const Tree& tree,
1401 bool address_printing_enabled)
1408 static void ResetObjectCounter() { object_counter_ = 0; }
1411 void PrintObject(
size_t object_index);
1412 void PrintObjectHeader(
const Tree::Object&
object);
1413 void PrintFieldHeader();
1414 void PrintFieldFooter();
1415 void PrintFieldStart(
const std::string& name);
1416 void PrintFieldEnd();
1417 void PrintObjectField(
const Tree::ObjectField& field);
1418 void PrintStringField(
const Tree::StringField& field);
1419 void PrintTableField(
const Tree::TableField& field);
1426 static size_t object_counter_;
1429 size_t HtmlTreePrinter::object_counter_ = 0;
1431 void HtmlTreePrinter::Print() {
1432 const std::vector<size_t>& roots =
tree_.GetRootObjectIndices();
1433 for (
size_t i = 0; i < roots.size(); ++i)
1434 PrintObject(roots[i]);
1437 void HtmlTreePrinter::PrintObject(
size_t object_index) {
1438 const Tree::Object&
object =
tree_.GetObject(object_index);
1441 PrintObjectHeader(
object);
1444 const bool has_fields = (!
object.string_fields.empty() ||
1445 !
object.table_fields.empty() ||
1446 !
object.object_fields.empty());
1450 for (
size_t i = 0; i <
object.string_fields.size(); ++i)
1452 for (
size_t i = 0; i <
object.table_fields.size(); ++i)
1454 for (
size_t i = 0; i <
object.object_fields.size(); ++i)
1461 for (
size_t i = 0; i <
object.child_object_indices.size(); ++i)
1465 out_ <<
"</ul></li>\n";
1468 void HtmlTreePrinter::PrintObjectHeader(
const Tree::Object&
object) {
1470 out_ <<
"<li><input type =\"checkbox\" checked=\"checked\" id=\"list-"
1471 << object_counter_ <<
"\"/><label for=\"list-" << object_counter_
1475 if (!
object.type.empty()) {
1476 out_ <<
"ION " <<
object.type;
1477 if (!
object.label.empty())
1478 out_ <<
" \"" <<
object.label <<
'\"';
1480 out_ <<
" [" << Pointer(
object.pointer) <<
']';
1482 out_ <<
"</label><ul>\n";
1487 void HtmlTreePrinter::PrintFieldHeader() {
1488 out_ <<
"<table class=\"nodes_field_table\">\n";
1491 void HtmlTreePrinter::PrintFieldFooter() {
1492 out_ <<
"</table>\n";
1495 void HtmlTreePrinter::PrintFieldStart(
const std::string& name) {
1496 out_ <<
"<tr><td class=\"name\">" << name <<
"</td><td class=\"value\">";
1499 void HtmlTreePrinter::PrintFieldEnd() {
1500 out_ <<
"</td></tr>\n";
1503 void HtmlTreePrinter::PrintObjectField(
const Tree::ObjectField& field) {
1504 PrintFieldStart(field.name);
1505 PrintObject(field.object_index);
1509 void HtmlTreePrinter::PrintStringField(
const Tree::StringField& field) {
1510 PrintFieldStart(field.name);
1511 out_ << field.value;
1515 void HtmlTreePrinter::PrintTableField(
const Tree::TableField& field) {
1516 PrintFieldStart(field.name);
1517 const Tree::Table& table = field.table;
1518 if (table.GetSize()) {
1519 out_ <<
"<table class=\"nodes_field_value_table\">\n";
1520 const size_t num_rows = table.GetHeight();
1521 const size_t num_columns = table.GetWidth();
1522 for (
size_t row = 0; row < num_rows; ++row) {
1524 for (
size_t col = 0; col < num_columns; ++col) {
1525 const std::string& cell = table.Get(col, row);
1526 if (table.HasLabelColumn() && col == 0)
1527 out_ <<
"<td><span class=\"table_label\">" << cell <<
"</span></td>";
1529 out_ <<
"<td>" << cell <<
"</td>\n";
1533 out_ <<
"</table>\n";
1555 HtmlTreePrinter::ResetObjectCounter();
1560 TreeBuilder tb(address_printing_enabled_, full_shape_printing_enabled_);
1561 const Tree tree = tb.BuildTree(*node);
1563 if (format_ ==
kText) {
1564 TextTreePrinter(out, tree, address_printing_enabled_).Print();
1566 HtmlTreePrinter(out, tree, address_printing_enabled_).Print();
bool IsInvalidReference(const T &value)
IsInvalidReference() returns true if a passed const reference of type T has an address of InvalidRefe...
Matrix< 4, float > Matrix4f
base::ReferentPtr< Node >::Type NodePtr
base::ReferentPtr< Image >::Type ImagePtr
Printer()
Printer class functions.
base::ReferentPtr< Shape >::Type ShapePtr
Convenience typedef for shared pointer to a Shape.
Range< 1, int32 > Range1i
bool full_shape_printing_enabled_
std::vector< size_t > cur_objects_
Matrix< 3, float > Matrix3f
base::ReferentPtr< CubeMapTexture >::Type CubeMapTexturePtr
Convenience typedef for shared pointer to a CubeMapTexture.
void PrintScene(const gfx::NodePtr &node, std::ostream &out)
Prints the scene graph rooted by the given node.
std::ostream & operator<<(std::ostream &os, const DateTime &dtime)
const size_t object_index_
base::ReferentPtr< StateTable >::Type StateTablePtr
Convenience typedef for shared pointer to a StateTable.
std::vector< size_t > root_objects_
std::vector< size_t > child_object_indices
base::ReferentPtr< Sampler >::Type SamplerPtr
Convenience typedef for shared pointer to a Sampler.
std::vector< StringField > string_fields
base::ReferentPtr< IndexBuffer >::Type IndexBufferPtr
std::string ValueToString(const T &val)
ValueToString.
static const char * GetString(EnumType e)
Returns a string corresponding to an enum.
const Grid & image
The original monochrome image data, as doubles (0 - 1).
base::ReferentPtr< ShaderProgram >::Type ShaderProgramPtr
Copyright 2016 Google Inc.
std::vector< ObjectField > object_fields
Matrix< 2, float > Matrix2f
Dimension- and type-specific typedefs.
#define DCHECK_EQ(val1, val2)
TexturePtr texture
The Texture to add sub-image data to.
base::ReferentPtr< AttributeArray >::Type AttributeArrayPtr
Convenience typedef for shared pointer to a AttributeArray.
base::ReferentPtr< UniformBlock >::Type UniformBlockPtr
Convenience typedef for shared pointer to a UniformBlock.
std::set< const AttributeArray * > added_attribute_arrays_
std::vector< TableField > table_fields
base::ReferentPtr< ShaderInputRegistry >::Type ShaderInputRegistryPtr
Convenience typedef for shared pointer to a ShaderInputRegistry.
base::ReferentPtr< BufferObject >::Type BufferObjectPtr
Convenience typedef for shared pointer to a BufferObject.
std::vector< Object > all_objects_
bool address_printing_enabled_
base::ReferentPtr< Texture >::Type TexturePtr
Convenience typedef for shared pointer to a Texture.
#define DCHECK_LT(val1, val2)
Range< 1, float > Range1f