render_tree.cc 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410
  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "gpu/tools/compositor_model_bench/render_tree.h"
  5. #include <memory>
  6. #include <sstream>
  7. #include <vector>
  8. #include "base/files/file_path.h"
  9. #include "base/files/file_util.h"
  10. #include "base/json/json_reader.h"
  11. #include "base/json/json_writer.h"
  12. #include "base/logging.h"
  13. #include "base/values.h"
  14. #include "gpu/tools/compositor_model_bench/shaders.h"
  15. using base::JSONReader;
  16. using base::JSONWriter;
  17. using base::ReadFileToString;
  18. using base::Value;
  19. GLenum TextureFormatFromString(const std::string& format) {
  20. if (format == "RGBA")
  21. return GL_RGBA;
  22. if (format == "RGB")
  23. return GL_RGB;
  24. if (format == "LUMINANCE")
  25. return GL_LUMINANCE;
  26. return GL_INVALID_ENUM;
  27. }
  28. const char* TextureFormatName(GLenum format) {
  29. switch (format) {
  30. case GL_RGBA:
  31. return "RGBA";
  32. case GL_RGB:
  33. return "RGB";
  34. case GL_LUMINANCE:
  35. return "LUMINANCE";
  36. default:
  37. return "(unknown format)";
  38. }
  39. }
  40. int FormatBytesPerPixel(GLenum format) {
  41. switch (format) {
  42. case GL_RGBA:
  43. return 4;
  44. case GL_RGB:
  45. return 3;
  46. case GL_LUMINANCE:
  47. return 1;
  48. default:
  49. return 0;
  50. }
  51. }
  52. RenderNode::RenderNode() {
  53. }
  54. RenderNode::~RenderNode() {
  55. }
  56. void RenderNode::Accept(RenderNodeVisitor* v) {
  57. v->BeginVisitRenderNode(this);
  58. v->EndVisitRenderNode(this);
  59. }
  60. ContentLayerNode::ContentLayerNode() {
  61. }
  62. ContentLayerNode::~ContentLayerNode() {
  63. }
  64. void ContentLayerNode::Accept(RenderNodeVisitor* v) {
  65. v->BeginVisitContentLayerNode(this);
  66. for (auto& child : children_) {
  67. child->Accept(v);
  68. }
  69. v->EndVisitContentLayerNode(this);
  70. }
  71. CCNode::CCNode() {
  72. }
  73. CCNode::~CCNode() {
  74. }
  75. void CCNode::Accept(RenderNodeVisitor* v) {
  76. v->BeginVisitCCNode(this);
  77. v->EndVisitCCNode(this);
  78. }
  79. RenderNodeVisitor::~RenderNodeVisitor() {
  80. }
  81. void RenderNodeVisitor::BeginVisitContentLayerNode(ContentLayerNode* v) {
  82. this->BeginVisitRenderNode(v);
  83. }
  84. void RenderNodeVisitor::BeginVisitCCNode(CCNode* v) {
  85. this->BeginVisitRenderNode(v);
  86. }
  87. void RenderNodeVisitor::EndVisitRenderNode(RenderNode* v) {
  88. }
  89. void RenderNodeVisitor::EndVisitContentLayerNode(ContentLayerNode* v) {
  90. this->EndVisitRenderNode(v);
  91. }
  92. void RenderNodeVisitor::EndVisitCCNode(CCNode* v) {
  93. this->EndVisitRenderNode(v);
  94. }
  95. std::unique_ptr<RenderNode> InterpretNode(const base::Value& node);
  96. // Makes sure that the key exists and has the type we expect.
  97. bool VerifyDictionaryEntry(const base::Value& node,
  98. const std::string& key,
  99. Value::Type type) {
  100. const Value* value = node.FindKey(key);
  101. if (!value) {
  102. LOG(ERROR) << "Missing value for key: " << key;
  103. return false;
  104. }
  105. if (value->type() != type) {
  106. LOG(ERROR) << key
  107. << " did not have the expected type "
  108. "(expected "
  109. << base::Value::GetTypeName(type) << ")";
  110. return false;
  111. }
  112. return true;
  113. }
  114. // Makes sure that the list entry has the type we expect.
  115. bool VerifyListEntry(const base::Value& list,
  116. int index,
  117. Value::Type type,
  118. const char* listName = nullptr) {
  119. // Assume the index is valid (since we'll be able to generate a better
  120. // error message for this elsewhere.)
  121. if (list.GetListDeprecated()[index].type() != type) {
  122. LOG(ERROR) << (listName ? listName : "List") << "element " << index
  123. << " did not have the expected type (expected "
  124. << base::Value::GetTypeName(type) << ")\n";
  125. return false;
  126. }
  127. return true;
  128. }
  129. bool InterpretCommonContents(const base::Value& node, RenderNode* c) {
  130. if (!VerifyDictionaryEntry(node, "layerID", Value::Type::INTEGER) ||
  131. !VerifyDictionaryEntry(node, "width", Value::Type::INTEGER) ||
  132. !VerifyDictionaryEntry(node, "height", Value::Type::INTEGER) ||
  133. !VerifyDictionaryEntry(node, "drawsContent", Value::Type::BOOLEAN) ||
  134. !VerifyDictionaryEntry(node, "targetSurfaceID", Value::Type::INTEGER) ||
  135. !VerifyDictionaryEntry(node, "transform", Value::Type::LIST)) {
  136. return false;
  137. }
  138. c->set_layerID(node.FindIntKey("layerID").value());
  139. c->set_width(node.FindIntKey("width").value());
  140. c->set_height(node.FindIntKey("height").value());
  141. c->set_drawsContent(node.FindBoolKey("drawsContent").value());
  142. c->set_targetSurface(node.FindIntKey("targetSurfaceID").value());
  143. const Value* transform = node.FindKey("transform");
  144. if (transform->GetListDeprecated().size() != 16) {
  145. LOG(ERROR) << "4x4 transform matrix did not have 16 elements";
  146. return false;
  147. }
  148. float transform_mat[16];
  149. for (int i = 0; i < 16; ++i) {
  150. if (!VerifyListEntry(*transform, i, Value::Type::DOUBLE, "Transform"))
  151. return false;
  152. transform_mat[i] = transform->GetListDeprecated()[i].GetDouble();
  153. }
  154. c->set_transform(transform_mat);
  155. const Value* tiles_dict = node.FindKey("tiles");
  156. if (!tiles_dict)
  157. return true;
  158. if (!VerifyDictionaryEntry(node, "tiles", Value::Type::DICTIONARY))
  159. return false;
  160. if (!VerifyDictionaryEntry(*tiles_dict, "dim", Value::Type::LIST))
  161. return false;
  162. const Value* dim = tiles_dict->FindKey("dim");
  163. if (!VerifyListEntry(*dim, 0, Value::Type::INTEGER, "Tile dimension") ||
  164. !VerifyListEntry(*dim, 1, Value::Type::INTEGER, "Tile dimension")) {
  165. return false;
  166. }
  167. c->set_tile_width(dim->GetListDeprecated()[0].GetInt());
  168. c->set_tile_height(dim->GetListDeprecated()[1].GetInt());
  169. if (!VerifyDictionaryEntry(*tiles_dict, "info", Value::Type::LIST))
  170. return false;
  171. const Value* tiles = tiles_dict->FindKey("info");
  172. for (unsigned int i = 0; i < tiles->GetListDeprecated().size(); ++i) {
  173. if (!VerifyListEntry(*tiles, i, Value::Type::DICTIONARY, "Tile info"))
  174. return false;
  175. const Value& tdict = tiles->GetListDeprecated()[i];
  176. if (!VerifyDictionaryEntry(tdict, "x", Value::Type::INTEGER) ||
  177. !VerifyDictionaryEntry(tdict, "y", Value::Type::INTEGER)) {
  178. return false;
  179. }
  180. Tile t;
  181. t.x = tdict.FindIntKey("x").value();
  182. t.y = tdict.FindIntKey("y").value();
  183. const Value* texID = tdict.FindKey("texID");
  184. if (texID) {
  185. if (!VerifyDictionaryEntry(tdict, "texID", Value::Type::INTEGER))
  186. return false;
  187. t.texID = texID->GetInt();
  188. } else {
  189. t.texID = -1;
  190. }
  191. c->add_tile(t);
  192. }
  193. return true;
  194. }
  195. bool InterpretCCData(const base::Value& node, CCNode* c) {
  196. if (!VerifyDictionaryEntry(node, "vertex_shader", Value::Type::STRING) ||
  197. !VerifyDictionaryEntry(node, "fragment_shader", Value::Type::STRING) ||
  198. !VerifyDictionaryEntry(node, "textures", Value::Type::LIST)) {
  199. return false;
  200. }
  201. std::string vertex_shader_name = *node.FindStringKey("vertex_shader");
  202. std::string fragment_shader_name = *node.FindStringKey("fragment_shader");
  203. c->set_vertex_shader(ShaderIDFromString(vertex_shader_name));
  204. c->set_fragment_shader(ShaderIDFromString(fragment_shader_name));
  205. const Value* textures = node.FindKey("textures");
  206. for (unsigned int i = 0; i < textures->GetListDeprecated().size(); ++i) {
  207. if (!VerifyListEntry(*textures, i, Value::Type::DICTIONARY, "Tex list"))
  208. return false;
  209. const Value& tex = textures->GetListDeprecated()[i];
  210. if (!VerifyDictionaryEntry(tex, "texID", Value::Type::INTEGER) ||
  211. !VerifyDictionaryEntry(tex, "height", Value::Type::INTEGER) ||
  212. !VerifyDictionaryEntry(tex, "width", Value::Type::INTEGER) ||
  213. !VerifyDictionaryEntry(tex, "format", Value::Type::STRING)) {
  214. return false;
  215. }
  216. Texture t;
  217. t.texID = tex.FindIntKey("texID").value();
  218. t.height = tex.FindIntKey("height").value();
  219. t.width = tex.FindIntKey("width").value();
  220. const std::string* format_name = tex.FindStringKey("format");
  221. t.format = TextureFormatFromString(*format_name);
  222. if (t.format == GL_INVALID_ENUM) {
  223. LOG(ERROR) << "Unrecognized texture format in layer " << c->layerID()
  224. << " (format: " << *format_name
  225. << ")\n"
  226. "The layer had "
  227. << textures->GetListDeprecated().size() << " children.";
  228. return false;
  229. }
  230. c->add_texture(t);
  231. }
  232. if (c->vertex_shader() == SHADER_UNRECOGNIZED) {
  233. LOG(ERROR) << "Unrecognized vertex shader name, layer " << c->layerID()
  234. << " (shader: " << vertex_shader_name << ")";
  235. return false;
  236. }
  237. if (c->fragment_shader() == SHADER_UNRECOGNIZED) {
  238. LOG(ERROR) << "Unrecognized fragment shader name, layer " << c->layerID()
  239. << " (shader: " << fragment_shader_name << ")";
  240. return false;
  241. }
  242. return true;
  243. }
  244. std::unique_ptr<RenderNode> InterpretContentLayer(const base::Value& node) {
  245. auto n = std::make_unique<ContentLayerNode>();
  246. if (!InterpretCommonContents(node, n.get()))
  247. return nullptr;
  248. if (!VerifyDictionaryEntry(node, "type", Value::Type::STRING) ||
  249. !VerifyDictionaryEntry(node, "skipsDraw", Value::Type::BOOLEAN) ||
  250. !VerifyDictionaryEntry(node, "children", Value::Type::LIST)) {
  251. return nullptr;
  252. }
  253. DCHECK_EQ(*node.FindStringKey("type"), "ContentLayer");
  254. n->set_skipsDraw(node.FindBoolKey("skipsDraw").value());
  255. const Value* children = node.FindKey("children");
  256. for (unsigned int i = 0; i < children->GetListDeprecated().size(); ++i) {
  257. const Value& child_node = children->GetListDeprecated()[i];
  258. if (!child_node.is_dict())
  259. continue;
  260. std::unique_ptr<RenderNode> child = InterpretNode(child_node);
  261. if (child)
  262. n->add_child(child.release());
  263. }
  264. return std::move(n);
  265. }
  266. std::unique_ptr<RenderNode> InterpretCanvasLayer(const base::Value& node) {
  267. auto n = std::make_unique<CCNode>();
  268. if (!InterpretCommonContents(node, n.get()))
  269. return nullptr;
  270. if (!VerifyDictionaryEntry(node, "type", Value::Type::STRING))
  271. return nullptr;
  272. DCHECK_EQ(*node.FindStringKey("type"), "CanvasLayer");
  273. if (!InterpretCCData(node, n.get()))
  274. return nullptr;
  275. return std::move(n);
  276. }
  277. std::unique_ptr<RenderNode> InterpretVideoLayer(const base::Value& node) {
  278. auto n = std::make_unique<CCNode>();
  279. if (!InterpretCommonContents(node, n.get()))
  280. return nullptr;
  281. if (!VerifyDictionaryEntry(node, "type", Value::Type::STRING))
  282. return nullptr;
  283. DCHECK_EQ(*node.FindStringKey("type"), "VideoLayer");
  284. if (!InterpretCCData(node, n.get()))
  285. return nullptr;
  286. return std::move(n);
  287. }
  288. std::unique_ptr<RenderNode> InterpretImageLayer(const base::Value& node) {
  289. auto n = std::make_unique<CCNode>();
  290. if (!InterpretCommonContents(node, n.get()))
  291. return nullptr;
  292. if (!VerifyDictionaryEntry(node, "type", Value::Type::STRING))
  293. return nullptr;
  294. DCHECK_EQ(*node.FindStringKey("type"), "ImageLayer");
  295. if (!InterpretCCData(node, n.get()))
  296. return nullptr;
  297. return std::move(n);
  298. }
  299. std::unique_ptr<RenderNode> InterpretNode(const base::Value& node) {
  300. if (!VerifyDictionaryEntry(node, "type", Value::Type::STRING))
  301. return nullptr;
  302. const std::string* type = node.FindStringKey("type");
  303. if (*type == "ContentLayer")
  304. return InterpretContentLayer(node);
  305. if (*type == "CanvasLayer")
  306. return InterpretCanvasLayer(node);
  307. if (*type == "VideoLayer")
  308. return InterpretVideoLayer(node);
  309. if (*type == "ImageLayer")
  310. return InterpretImageLayer(node);
  311. std::string outjson;
  312. JSONWriter::WriteWithOptions(node, base::JSONWriter::OPTIONS_PRETTY_PRINT,
  313. &outjson);
  314. LOG(ERROR) << "Unrecognized node type! JSON:\n\n"
  315. "-----------------------\n"
  316. << outjson << "-----------------------";
  317. return nullptr;
  318. }
  319. std::unique_ptr<RenderNode> BuildRenderTreeFromFile(
  320. const base::FilePath& path) {
  321. LOG(INFO) << "Reading " << path.LossyDisplayName();
  322. std::string contents;
  323. if (!ReadFileToString(path, &contents))
  324. return nullptr;
  325. auto result = JSONReader::ReadAndReturnValueWithError(
  326. contents, base::JSON_ALLOW_TRAILING_COMMAS);
  327. if (!result.has_value()) {
  328. LOG(ERROR) << "Failed to parse JSON file " << path.LossyDisplayName()
  329. << "\n(" << result.error().message << ")";
  330. return nullptr;
  331. } else if (!result->is_dict()) {
  332. LOG(ERROR) << "Failed to parse JSON file " << path.LossyDisplayName()
  333. << "\n(expecting a list.)";
  334. return nullptr;
  335. }
  336. return InterpretContentLayer(*result);
  337. }