Ion
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
resourcehandler.cc
Go to the documentation of this file.
1 
18 #if !ION_PRODUCTION
19 
21 
22 #include <sstream>
23 #include <string>
24 #include <vector>
25 
26 #include "ion/base/allocator.h"
27 #include "ion/base/invalid.h"
28 #include "ion/base/stringutils.h"
31 #include "ion/gfx/image.h"
33 #include "ion/gfx/tracinghelper.h"
36 #include "ion/image/renderutils.h"
37 
38 ION_REGISTER_ASSETS(IonRemoteResourcesRoot);
39 
40 namespace ion {
41 namespace remote {
42 
43 namespace {
44 
45 using gfx::AttributeArray;
46 using gfx::BufferObject;
47 using gfx::CubeMapTexture;
49 using gfx::FramebufferObject;
50 using gfx::Image;
51 using gfx::ImagePtr;
52 using gfx::Renderer;
53 using gfx::RendererPtr;
54 using gfx::ResourceManager;
55 using gfx::Sampler;
56 using gfx::Shader;
57 using gfx::ShaderProgram;
58 using gfx::TextureBase;
59 using gfx::Texture;
60 using gfx::TexturePtr;
70 using std::bind;
71 using std::placeholders::_1;
72 
73 typedef ResourceManager::ArrayInfo ArrayInfo;
74 typedef ResourceManager::BufferInfo BufferInfo;
75 typedef ResourceManager::FramebufferInfo FramebufferInfo;
76 typedef ResourceManager::RenderbufferInfo RenderbufferInfo;
77 typedef ResourceManager::PlatformInfo PlatformInfo;
78 typedef ResourceManager::ProgramInfo ProgramInfo;
79 typedef ResourceManager::SamplerInfo SamplerInfo;
80 typedef ResourceManager::ShaderInfo ShaderInfo;
81 typedef ResourceManager::TextureImageInfo TextureImageInfo;
82 typedef ResourceManager::TextureInfo TextureInfo;
83 
85 
90 
91 
92 class Indent {
93  public:
94  explicit Indent(size_t spaces) : indent_(spaces, ' '), spaces_(spaces) {}
95 
97  friend std::ostream& operator<<(std::ostream& out, const Indent& indent) {
98  out << indent.indent_;
99  return out;
100  }
101 
103  friend const Indent operator+(const Indent& indent, size_t spaces) {
104  return Indent(indent.spaces_ + spaces);
105  }
106 
107  private:
108  const std::string indent_;
109  const size_t spaces_;
110 };
111 
113 static const std::string EscapeJson(const std::string& str) {
114  std::string ret = base::ReplaceString(str, "\\", "\\\\");
115  ret = base::ReplaceString(ret, "\"", "\\\"");
116  ret = base::EscapeNewlines(ret);
117  return ret;
118 }
119 
121 
128 
129 
130 class RenderTextureCallback : public TextureImageCallback {
131  public:
132  typedef base::ReferentPtr<RenderTextureCallback>::Type RefPtr;
133 
134  RenderTextureCallback(const RendererPtr& renderer, bool do_wait)
135  : TextureImageCallback(do_wait),
136  renderer_(renderer) {}
137 
139  void Callback(const std::vector<TextureImageInfo>& data);
140 
141  private:
143  ~RenderTextureCallback() override {}
144 
147  void RenderTextureImage(const RendererPtr& renderer, TextureImageInfo* info);
148  void RenderCubeMapTextureImages(const RendererPtr& renderer,
149  TextureImageInfo* info);
150 
153 };
154 
155 void RenderTextureCallback::Callback(
156  const std::vector<TextureImageInfo>& data) {
158  RefPtr holder(this);
159 
162  const bool flag_was_set =
163  renderer_->GetFlags().test(Renderer::kProcessInfoRequests);
164  renderer_->ClearFlag(Renderer::kProcessInfoRequests);
165 
167  std::vector<TextureImageInfo> new_data = data;
168  const size_t data_count = new_data.size();
169  for (size_t i = 0; i < data_count; ++i) {
170  TextureImageInfo* info = &new_data[i];
171  if (info->texture.Get()) {
172  if (info->texture->GetTextureType() == TextureBase::kTexture)
174  else
175  RenderCubeMapTextureImages(renderer_, info);
176  }
177  }
178 
179  if (flag_was_set)
180  renderer_->SetFlag(Renderer::kProcessInfoRequests);
181 
183  TextureImageCallback::Callback(new_data);
184 }
185 
187  const RendererPtr& renderer, TextureImageInfo* info) {
188  DCHECK(info);
189  DCHECK_EQ(info->texture->GetTextureType(), TextureBase::kTexture);
190  DCHECK_EQ(info->images.size(), 1U);
191 
192  const ImagePtr& input_image = info->images[0];
193  if (input_image.Get()) {
194  TexturePtr tex(static_cast<Texture*>(info->texture.Get()));
195  const base::AllocatorPtr& sta =
196  tex->GetAllocator()->GetAllocatorForLifetime(base::kShortTerm);
197  ImagePtr output_image = image::RenderTextureImage(
198  tex, input_image->GetWidth(), input_image->GetHeight(), renderer, sta);
199  if (output_image.Get())
200  info->images[0] = output_image;
201  }
202 }
203 
204 void RenderTextureCallback::RenderCubeMapTextureImages(
205  const RendererPtr& renderer, TextureImageInfo* info) {
206  DCHECK(info);
207  DCHECK_EQ(info->texture->GetTextureType(), TextureBase::kCubeMapTexture);
208  DCHECK_EQ(info->images.size(), 6U);
209 
210  CubeMapTexturePtr tex(static_cast<CubeMapTexture*>(info->texture.Get()));
211  const base::AllocatorPtr& sta =
212  tex->GetAllocator()->GetAllocatorForLifetime(base::kShortTerm);
213  for (int i = 0; i < 6; ++i) {
214  const ImagePtr& input_image = info->images[i];
215  const CubeMapTexture::CubeFace face =
216  static_cast<CubeMapTexture::CubeFace>(i);
217  ImagePtr output_image =
219  tex, face, input_image->GetWidth(), input_image->GetHeight(),
220  renderer, sta);
221  if (output_image.Get())
222  info->images[i] = output_image;
223  }
224 }
225 
227 
232 
233 
235 static const std::string ConvertAttachmentToJson(
236  const Indent& indent,
237  const FramebufferInfo::Attachment& info,
238  const RenderbufferInfo& rb_info) {
239  gfx::TracingHelper helper;
240  std::ostringstream str;
241  const Indent indent2 = indent + 2;
242 
243  str << indent << "\"type\": \""
244  << (info.type ? helper.ToString("GLenum", info.type) : "GL_NONE")
245  << "\",\n";
246  str << indent;
247  if (info.type == GL_TEXTURE)
248  str << "\"texture_glid\": " << info.value << ",\n";
249  else
250  str << "\"value\": " << info.value << ",\n";
251  str << indent << "\"mipmap_level\": " << info.level << ",\n";
252  str << indent << "\"cube_face\": \""
253  << (info.cube_face ? helper.ToString("GLenum", info.cube_face)
254  : "GL_NONE") << "\",\n";
255  str << indent << "\"renderbuffer\": {\n";
256  str << indent2 << "\"object_id\": " << rb_info.id << ",\n";
257  str << indent2 << "\"label\": " << "\"" << rb_info.label << "\",\n";
258  str << indent2 << "\"width\": " << rb_info.width << ",\n";
259  str << indent2 << "\"height\": " << rb_info.height << ",\n";
260  str << indent2 << "\"internal_format\": \""
261  << helper.ToString("GLenum", rb_info.internal_format) << "\",\n";
262  str << indent2 << "\"red_size\": " << rb_info.red_size << ",\n";
263  str << indent2 << "\"green_size\": " << rb_info.green_size << ",\n";
264  str << indent2 << "\"blue_size\": " << rb_info.blue_size << ",\n";
265  str << indent2 << "\"alpha_size\": " << rb_info.alpha_size << ",\n";
266  str << indent2 << "\"depth_size\": " << rb_info.depth_size << ",\n";
267  str << indent2 << "\"stencil_size\": " << rb_info.stencil_size << "\n";
268  str << indent << "}\n";
269  return str.str();
270 }
271 
272 const std::string ConvertEnumVectorToJson(const std::vector<GLenum>& vec) {
273  gfx::TracingHelper helper;
274  std::ostringstream str;
275  const size_t count = vec.size();
276  for (size_t i = 0; i < count; ++i) {
277  if (i)
278  str << ", ";
279  str << helper.ToString("GLenum", vec[i]);
280  }
281 
282  return str.str();
283 }
284 
286 template <typename T>
287 static const std::string ConvertShaderInputToJson(const Indent& indent,
288  const T& input) {
289  gfx::TracingHelper helper;
290  std::ostringstream str;
291  str << indent << "\"name\": \"" << input.name << "\",\n";
292  str << indent << "\"index\": " << input.index << ",\n";
293  str << indent << "\"size\": " << input.size << ",\n";
294  str << indent << "\"type\": \"" << helper.ToString("GLenum", input.type)
295  << "\"\n";
296  return str.str();
297 }
298 
300 static const std::string ConvertProgramAttributesToJson(
301  const Indent& indent, const std::vector<ProgramInfo::Attribute>& attrs) {
302  gfx::TracingHelper helper;
303  std::ostringstream str;
304  const size_t count = attrs.size();
305  for (size_t i = 0; i < count; ++i) {
306  str << indent << "{\n";
307  str << ConvertShaderInputToJson(indent + 2, attrs[i]);
308  str << indent << "}" << (i < count - 1U ? "," : "") << "\n";
309  }
310  return str.str();
311 }
312 
314 template <typename T>
315 static void StreamProgramUniform(const ProgramInfo::Uniform& uniform,
316  std::ostream& str) { // NOLINT
317  str << "\"";
318  if (uniform.size > 1) {
319  str << "[";
320  for (GLint i = 0; i < uniform.size; i++) {
321  if (i)
322  str << ", ";
323  str << uniform.value.GetValueAt<T>(i);
324  }
325  str << "]";
326  } else {
327  str << uniform.value.Get<T>();
328  }
329  str << "\"";
330 }
331 
333 template <typename T>
334 static void StreamProgramUniformVector(const ProgramInfo::Uniform& uniform,
335  std::ostream& str) { // NOLINT
336  str << "\"";
337  if (uniform.size > 1) {
338  str << "[";
339  for (GLint i = 0; i < uniform.size; i++) {
340  if (i)
341  str << ", ";
342  uniform.value.GetValueAt<T>(i).Print(str, 'V');
343  }
344  str << "]";
345  } else {
346  uniform.value.Get<T>().Print(str, 'V');
347  }
348  str << "\"";
349 }
350 
352 static const std::string ConvertProgramUniformsToJson(
353  const Indent& indent, const std::vector<ProgramInfo::Uniform>& uniforms) {
354  gfx::TracingHelper helper;
355  std::ostringstream str;
356  const Indent indent2 = indent + 2;
357 
358  const size_t count = uniforms.size();
359  for (size_t i = 0; i < count; ++i) {
360  const ProgramInfo::Uniform& u = uniforms[i];
361  str << indent << "{\n";
362  str << indent2 << "\"value\": ";
363  switch (u.type) {
364  case GL_FLOAT:
365  StreamProgramUniform<float>(u, str);
366  break;
367  case GL_FLOAT_VEC2:
368  StreamProgramUniformVector<math::VectorBase2f>(u, str);
369  break;
370  case GL_FLOAT_VEC3:
371  StreamProgramUniformVector<math::VectorBase3f>(u, str);
372  break;
373  case GL_FLOAT_VEC4:
374  StreamProgramUniformVector<math::VectorBase4f>(u, str);
375  break;
376  case GL_INT:
377  case GL_INT_SAMPLER_1D:
378  case GL_INT_SAMPLER_1D_ARRAY:
379  case GL_INT_SAMPLER_2D:
380  case GL_INT_SAMPLER_2D_ARRAY:
381  case GL_INT_SAMPLER_3D:
382  case GL_INT_SAMPLER_CUBE:
383  case GL_INT_SAMPLER_CUBE_MAP_ARRAY:
384  case GL_SAMPLER_1D:
385  case GL_SAMPLER_1D_ARRAY:
386  case GL_SAMPLER_1D_ARRAY_SHADOW:
387  case GL_SAMPLER_1D_SHADOW:
388  case GL_SAMPLER_2D:
389  case GL_SAMPLER_2D_ARRAY:
390  case GL_SAMPLER_2D_ARRAY_SHADOW:
391  case GL_SAMPLER_2D_MULTISAMPLE:
392  case GL_SAMPLER_2D_MULTISAMPLE_ARRAY:
393  case GL_SAMPLER_2D_SHADOW:
394  case GL_SAMPLER_3D:
395  case GL_SAMPLER_CUBE:
396  case GL_SAMPLER_CUBE_MAP_ARRAY:
397  case GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW:
398  case GL_SAMPLER_CUBE_SHADOW:
400  case GL_UNSIGNED_INT_SAMPLER_1D:
401  case GL_UNSIGNED_INT_SAMPLER_1D_ARRAY:
402  case GL_UNSIGNED_INT_SAMPLER_2D:
403  case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
404  case GL_UNSIGNED_INT_SAMPLER_3D:
405  case GL_UNSIGNED_INT_SAMPLER_CUBE:
406  case GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY:
407  StreamProgramUniform<int>(u, str);
408  break;
409  case GL_INT_VEC2:
410  StreamProgramUniformVector<math::VectorBase2i>(u, str);
411  break;
412  case GL_INT_VEC3:
413  StreamProgramUniformVector<math::VectorBase3i>(u, str);
414  break;
415  case GL_INT_VEC4:
416  StreamProgramUniformVector<math::VectorBase4i>(u, str);
417  break;
418  case GL_UNSIGNED_INT:
419  StreamProgramUniform<uint32>(u, str);
420  break;
421  case GL_UNSIGNED_INT_VEC2:
422  StreamProgramUniformVector<math::VectorBase2ui>(u, str);
423  break;
424  case GL_UNSIGNED_INT_VEC3:
425  StreamProgramUniformVector<math::VectorBase3ui>(u, str);
426  break;
427  case GL_UNSIGNED_INT_VEC4:
428  StreamProgramUniformVector<math::VectorBase4ui>(u, str);
429  break;
430  case GL_FLOAT_MAT2:
431  StreamProgramUniform<math::Matrix2f>(u, str);
432  break;
433  case GL_FLOAT_MAT3:
434  StreamProgramUniform<math::Matrix3f>(u, str);
435  break;
436  case GL_FLOAT_MAT4:
437  StreamProgramUniform<math::Matrix4f>(u, str);
438  break;
439 #if !defined(ION_COVERAGE) // COV_NF_START
440  default:
441  break;
442 #endif // COV_NF_END
443  }
444  str << ",\n";
445  str << ConvertShaderInputToJson(indent + 2, u);
446  str << indent << "}" << (i < count - 1U ? "," : "") << "\n";
447  }
448  return str.str();
449 }
450 
455 template <typename InfoType>
456 static const std::string ConvertInfoToJson(const Indent& indent,
457  const InfoType& info) {
458  CHECK(false) << "Unspecialized ConvertInfoToJson() called.";
459  return std::string();
460 }
461 
462 template <>
463 const std::string ConvertInfoToJson(const Indent& indent,
464  const PlatformInfo& info) {
465  std::ostringstream str;
466  const Indent indent2 = indent + 2;
467  const Indent indent4 = indent + 4;
468 
469  str << indent << "\"renderer\": \"" << info.renderer << "\",\n";
470  str << indent << "\"vendor\": \"" << info.vendor << "\",\n";
471  str << indent << "\"version_string\": \"" << info.version_string << "\",\n";
472  str << indent << "\"gl_version\": " << info.major_version << "."
473  << info.minor_version << ",\n";
474  str << indent << "\"glsl_version\": " << info.glsl_version << ",\n";
475  str << indent << "\"aliased_line_width_range\": \""
476  << info.aliased_line_width_range[0] << " - "
477  << info.aliased_line_width_range[1] << "\",\n";
478  str << indent << "\"aliased_point_size_range\": \""
479  << info.aliased_point_size_range[0] << " - "
480  << info.aliased_point_size_range[1] << "\",\n";
481  str << indent << "\"max_color_attachments\": "
482  << info.max_color_attachments << ",\n";
483  str << indent << "\"max_combined_texture_image_units\": "
484  << info.max_combined_texture_image_units << ",\n";
485  str << indent << "\"max_cube_map_texture_size\": "
486  << info.max_cube_map_texture_size << ",\n";
487  str << indent << "\"max_draw_buffers\": "
488  << info.max_draw_buffers << ",\n";
489  str << indent << "\"max_fragment_uniform_vectors\": "
490  << info.max_fragment_uniform_vectors << ",\n";
491  str << indent << "\"max_renderbuffer_size\": " << info.max_renderbuffer_size
492  << ",\n";
493  str << indent << "\"max_texture_image_units\": "
494  << info.max_texture_image_units << ",\n";
495  str << indent << "\"max_texture_size\": " << info.max_texture_size << ",\n";
496  str << indent << "\"max_transform_feedback_buffers\": "
497  << info.max_transform_feedback_buffers << ",\n";
498  str << indent << "\"max_transform_feedback_interleaved_components\": "
499  << info.max_transform_feedback_interleaved_components << ",\n";
500  str << indent << "\"max_transform_feedback_separate_attribs\": "
501  << info.max_transform_feedback_separate_attribs << ",\n";
502  str << indent << "\"max_transform_feedback_separate_components\": "
503  << info.max_transform_feedback_separate_components << ",\n";
504  str << indent << "\"max_varying_vectors\": " << info.max_varying_vectors
505  << ",\n";
506  str << indent << "\"max_vertex_attribs\": " << info.max_vertex_attribs
507  << ",\n";
508  str << indent << "\"max_vertex_texture_image_units\": "
509  << info.max_vertex_texture_image_units << ",\n";
510  str << indent << "\"max_vertex_uniform_vectors\": "
511  << info.max_vertex_uniform_vectors << ",\n";
512  str << indent << "\"max_viewport_dims\": \"" << info.max_viewport_dims[0]
513  << " x " << info.max_viewport_dims[1] << "\",\n";
514  str << indent << "\"transform_feedback_varying_max_length\": "
515  << info.transform_feedback_varying_max_length << ",\n";
516  str << indent << "\"compressed_texture_formats\": \""
517  << ConvertEnumVectorToJson(info.compressed_texture_formats) << "\",\n";
518  str << indent << "\"shader_binary_formats\": \""
519  << ConvertEnumVectorToJson(info.shader_binary_formats) << "\",\n";
520  str << indent << "\"extensions\": \"" << info.extensions << "\"\n";
521 
522  return str.str();
523 }
524 
525 
526 template <>
527 const std::string ConvertInfoToJson(const Indent& indent,
528  const ArrayInfo& info) {
529  gfx::TracingHelper helper;
530  std::ostringstream str;
531  const Indent indent2 = indent + 2;
532  const Indent indent4 = indent + 4;
533 
534  str << indent << "\"object_id\": " << info.id << ",\n";
535  str << indent << "\"label\": " << "\"" << info.label << "\",\n";
536  str << indent << "\"vertex_count\": " << info.vertex_count << ",\n";
537  str << indent << "\"attributes\": [\n";
538  const size_t count = info.attributes.size();
539  for (size_t i = 0; i < count; ++i) {
540  str << indent2 << "{\n";
541  str << indent4 << "\"buffer_glid\": " << info.attributes[i].buffer << ",\n";
542  str << indent4 << "\"enabled\": \""
543  << helper.ToString("GLboolean", info.attributes[i].enabled) << "\",\n";
544  str << indent4 << "\"size\": " << info.attributes[i].size << ",\n";
545  str << indent4 << "\"stride\": " << info.attributes[i].stride << ",\n";
546  str << indent4 << "\"type\": \""
547  << helper.ToString("GLenum", info.attributes[i].type) << "\",\n";
548  str << indent4 << "\"normalized\": \""
549  << helper.ToString("GLboolean", info.attributes[i].normalized)
550  << "\",\n";
551  str << indent4 << "\"pointer_or_offset\": \""
552  << helper.ToString("GLvoid*", info.attributes[i].pointer) << "\",\n";
553  str << indent4 << "\"value\": \"" << info.attributes[i].value << "\"\n";
554  str << indent2 << "}" << (i < count - 1U ? "," : "") << "\n";
555  }
556  str << indent << "]\n";
557 
558  return str.str();
559 }
560 
561 template <>
562 const std::string ConvertInfoToJson(const Indent& indent,
563  const BufferInfo& info) {
564  gfx::TracingHelper helper;
565  std::ostringstream str;
566  str << indent << "\"object_id\": " << info.id << ",\n";
567  str << indent << "\"label\": " << "\"" << info.label << "\",\n";
568  str << indent << "\"size\": " << info.size << ",\n";
569  str << indent << "\"usage\": \"" << helper.ToString("GLenum", info.usage)
570  << "\",\n";
571  str << indent << "\"mapped_pointer\": \""
572  << helper.ToString("GLvoid*", info.mapped_data) << "\",\n";
573  str << indent << "\"target\": \"" << helper.ToString("GLenum", info.target)
574  << "\"\n";
575  return str.str();
576 }
577 
578 template <>
579 const std::string ConvertInfoToJson(const Indent& indent,
580  const FramebufferInfo& info) {
581  std::ostringstream str;
582  const Indent indent2 = indent + 2;
583  str << indent << "\"object_id\": " << info.id << ",\n";
584  str << indent << "\"label\": " << "\"" << info.label << "\",\n";
585  str << indent << "\"attachment_color0\": {\n";
586  str << ConvertAttachmentToJson(
587  indent2, info.color0, info.color0_renderbuffer);
588  str << indent << "},\n";
589  str << indent << "\"attachment_depth\": {\n";
590  str << ConvertAttachmentToJson(indent2, info.depth, info.depth_renderbuffer);
591  str << indent << "},\n";
592  str << indent << "\"attachment_stencil\": {\n";
593  str << ConvertAttachmentToJson(
594  indent2, info.stencil, info.stencil_renderbuffer);
595  str << indent << "}\n";
596  return str.str();
597 }
598 
599 template <>
600 const std::string ConvertInfoToJson(const Indent& indent,
601  const ProgramInfo& info) {
602  gfx::TracingHelper helper;
603  std::ostringstream str;
604  const Indent indent2 = indent + 2;
605  str << indent << "\"object_id\": " << info.id << ",\n";
606  str << indent << "\"label\": " << "\"" << info.label << "\",\n";
607  str << indent << "\"vertex_shader_glid\": " << info.vertex_shader << ",\n";
608  str << indent << "\"fragment_shader_glid\": " << info.fragment_shader
609  << ",\n";
610  str << indent << "\"delete_status\": \""
611  << helper.ToString("GLboolean", info.delete_status) << "\",\n";
612  str << indent << "\"link_status\": \""
613  << helper.ToString("GLboolean", info.link_status) << "\",\n";
614  str << indent << "\"validate_status\": \""
615  << helper.ToString("GLboolean", info.validate_status) << "\",\n";
616  str << indent << "\"attributes\": [\n";
617  str << ConvertProgramAttributesToJson(indent2, info.attributes);
618  str << indent << "],\n";
619  str << indent << "\"uniforms\": [\n";
620  str << ConvertProgramUniformsToJson(indent2, info.uniforms);
621  str << indent << "],\n";
622  str << indent << "\"info_log\": \"" << EscapeJson(info.info_log)
623  << "\"\n";
624  return str.str();
625 }
626 
627 template <>
628 const std::string ConvertInfoToJson(const Indent& indent,
629  const SamplerInfo& info) {
630  gfx::TracingHelper helper;
631  std::ostringstream str;
632  str << indent << "\"object_id\": " << info.id << ",\n";
633  str << indent << "\"label\": " << "\"" << info.label << "\",\n";
634  str << indent << "\"compare_function\": \""
635  << helper.ToString("GLtextureenum", info.compare_func) << "\",\n";
636  str << indent << "\"compare_mode\": \""
637  << helper.ToString("GLtextureenum", info.compare_mode) << "\",\n";
638  str << indent << "\"max_anisotropy\": " << info.max_anisotropy << ",\n";
639  str << indent << "\"min_lod\": " << info.min_lod << ",\n";
640  str << indent << "\"max_lod\": " << info.max_lod << ",\n";
641  str << indent << "\"min_filter\": \""
642  << helper.ToString("GLenum", info.min_filter) << "\",\n";
643  str << indent << "\"mag_filter\": \""
644  << helper.ToString("GLenum", info.mag_filter) << "\",\n";
645  str << indent << "\"wrap_r\": \"" << helper.ToString("GLenum", info.wrap_r)
646  << "\",\n";
647  str << indent << "\"wrap_s\": \"" << helper.ToString("GLenum", info.wrap_s)
648  << "\",\n";
649  str << indent << "\"wrap_t\": \"" << helper.ToString("GLenum", info.wrap_t)
650  << "\"\n";
651  return str.str();
652 }
653 
654 template <>
655 const std::string ConvertInfoToJson(const Indent& indent,
656  const ShaderInfo& info) {
657  gfx::TracingHelper helper;
658  std::ostringstream str;
659  str << indent << "\"object_id\": " << info.id << ",\n";
660  str << indent << "\"label\": " << "\"" << info.label << "\",\n";
661  str << indent << "\"type\": \"" << helper.ToString("GLenum", info.type)
662  << "\",\n";
663  str << indent << "\"delete_status\": \""
664  << helper.ToString("GLboolean", info.delete_status) << "\",\n";
665  str << indent << "\"compile_status\": \""
666  << helper.ToString("GLboolean", info.compile_status) << "\",\n";
667  str << indent << "\"source\": \""
668  << base::MimeBase64EncodeString("<pre><code>" + info.source +
669  "</code></pre>") << "\",\n";
670  str << indent << "\"info_log\": \"" << EscapeJson(info.info_log)
671  << "\"\n";
672  return str.str();
673 }
674 
675 template <>
676 const std::string ConvertInfoToJson(const Indent& indent,
677  const TextureInfo& info) {
678  gfx::TracingHelper helper;
679  std::ostringstream str;
680  str << indent << "\"object_id\": " << info.id << ",\n";
681  str << indent << "\"label\": " << "\"" << info.label << "\",\n";
682  str << indent << "\"width\": " << info.width << ",\n";
683  str << indent << "\"height\": " << info.height<< ",\n";
684  str << indent << "\"format\": \"" << Image::GetFormatString(info.format)
685  << "\",\n";
686  str << indent << "\"sampler_glid\": " << info.sampler << ",\n";
687  str << indent << "\"base_level\": " << info.base_level << ",\n";
688  str << indent << "\"max_level\": " << info.max_level << ",\n";
689  str << indent << "\"compare_function\": \""
690  << helper.ToString("GLtextureenum", info.compare_func) << "\",\n";
691  str << indent << "\"compare_mode\": \""
692  << helper.ToString("GLtextureenum", info.compare_mode) << "\",\n";
693  str << indent << "\"max_anisotropy\": " << info.max_anisotropy << ",\n";
694  str << indent << "\"min_lod\": " << info.min_lod << ",\n";
695  str << indent << "\"max_lod\": " << info.max_lod << ",\n";
696  str << indent << "\"min_filter\": \""
697  << helper.ToString("GLenum", info.min_filter) << "\",\n";
698  str << indent << "\"mag_filter\": \""
699  << helper.ToString("GLenum", info.mag_filter) << "\",\n";
700  str << indent << "\"swizzle_red\": \""
701  << helper.ToString("GLtextureenum", info.swizzle_r) << "\",\n";
702  str << indent << "\"swizzle_green\": \""
703  << helper.ToString("GLtextureenum", info.swizzle_g) << "\",\n";
704  str << indent << "\"swizzle_blue\": \""
705  << helper.ToString("GLtextureenum", info.swizzle_b) << "\",\n";
706  str << indent << "\"swizzle_alpha\": \""
707  << helper.ToString("GLtextureenum", info.swizzle_a) << "\",\n";
708  str << indent << "\"wrap_r\": \"" << helper.ToString("GLenum", info.wrap_r)
709  << "\",\n";
710  str << indent << "\"wrap_s\": \"" << helper.ToString("GLenum", info.wrap_s)
711  << "\",\n";
712  str << indent << "\"wrap_t\": \"" << helper.ToString("GLenum", info.wrap_t)
713  << "\",\n";
714  str << indent << "\"target\": \"" << helper.ToString("GLenum", info.target)
715  << "\",\n";
716  str << indent << "\"last_image_unit\": \""
717  << helper.ToString("GLenum", info.unit) << "\"\n";
718  return str.str();
719 }
720 
723 template <typename ResourceType, typename InfoType>
724 void RequestInfo(
725  ResourceManager* manager,
726  const typename gfxutils::ResourceCallback<InfoType>::RefPtr& callback) {
727  manager->RequestAllResourceInfos<ResourceType, InfoType>(std::bind(
728  &gfxutils::ResourceCallback<InfoType>::Callback, callback.Get(), _1));
729 }
730 
733 template <>
734 void RequestInfo<PlatformInfo, PlatformInfo>(
735  ResourceManager* manager,
736  const gfxutils::ResourceCallback<PlatformInfo>::RefPtr& callback) {
737  manager->RequestPlatformInfo(std::bind(
738  &gfxutils::ResourceCallback<PlatformInfo>::Callback, callback.Get(), _1));
739 }
740 
742 template <typename ResourceType, typename InfoType>
743 const std::string BuildJsonStruct(const RendererPtr& renderer,
744  const std::string& name, const Indent& indent,
745  const bool wait_for_completion) {
747  ResourceManager* manager = renderer->GetResourceManager();
748  typedef gfxutils::ResourceCallback<InfoType> Callback;
749  typename Callback::RefPtr callback(new Callback(wait_for_completion));
750  RequestInfo<ResourceType, InfoType>(manager, callback);
751 
755  if (!wait_for_completion)
756  renderer->ProcessResourceInfoRequests();
757 
758  std::vector<InfoType> infos;
759  callback->WaitForCompletion(&infos);
760  std::ostringstream str;
761 
762  const Indent indent2 = indent + 2;
763  const Indent indent4 = indent + 4;
764 
766  str << indent << "\"" << name << "\": [\n";
767  const size_t count = infos.size();
768  for (size_t i = 0; i < count; ++i) {
769  str << indent2 << "{\n";
770  str << ConvertInfoToJson<InfoType>(indent4, infos[i]);
771  str << indent2 << "}" << (i < count - 1U ? "," : "") << "\n";
772  }
773 
775  str << indent << "]";
776  return str.str();
777 }
778 
781 static const std::string GetResourceList(const RendererPtr& renderer,
782  const HttpServer::QueryMap& args) {
783  const bool wait_for_completion = args.find("nonblocking") == args.end();
784  HttpServer::QueryMap::const_iterator it = args.find("types");
785 
786  std::ostringstream str;
787  if (it != args.end()) {
788  str << "{\n";
789  const Indent indent(2);
790  const std::vector<std::string> types = base::SplitString(it->second, ",");
791  const size_t count = types.size();
792  for (size_t i = 0; i < count; ++i) {
793  if (types[i] == "platform") {
794  str << BuildJsonStruct<PlatformInfo, PlatformInfo>(
795  renderer, "platform", indent, wait_for_completion);
796  } else if (types[i] == "buffers") {
797  str << BuildJsonStruct<BufferObject, BufferInfo>(
798  renderer, "buffers", indent, wait_for_completion);
799  } else if (types[i] == "framebuffers") {
800  str << BuildJsonStruct<FramebufferObject, FramebufferInfo>(
801  renderer, "framebuffers", indent, wait_for_completion);
802  } else if (types[i] == "programs") {
803  str << BuildJsonStruct<ShaderProgram, ProgramInfo>(
804  renderer, "programs", indent, wait_for_completion);
805  } else if (types[i] == "samplers") {
806  str << BuildJsonStruct<Sampler, SamplerInfo>(
807  renderer, "samplers", indent, wait_for_completion);
808  } else if (types[i] == "shaders") {
809  str << BuildJsonStruct<Shader, ShaderInfo>(renderer, "shaders", indent,
810  wait_for_completion);
811  } else if (types[i] == "textures") {
812  str << BuildJsonStruct<TextureBase, TextureInfo>(
813  renderer, "textures", indent, wait_for_completion);
814  } else if (types[i] == "vertex_arrays") {
815  str << BuildJsonStruct<AttributeArray, ArrayInfo>(
816  renderer, "vertex_arrays", indent, wait_for_completion);
817  } else {
819  continue;
820  }
821 
823  if (i < count - 1)
824  str << ",\n";
825  else
826  str << "\n";
827  }
828  str << "}\n";
829  }
830  return str.str();
831 }
832 
833 static const std::string GetBufferData(const RendererPtr& renderer,
834  const HttpServer::QueryMap& args) {
837  return std::string();
838 }
839 
842 static void WriteFaceIntoCubeMap(uint32 x_offset,
843  uint32 y_offset,
844  const ImagePtr& face,
845  const ImagePtr& cubemap) {
846  const uint32 x_offset_bytes = x_offset * 3;
847  const uint32 face_height = face->GetHeight();
848  const uint32 face_row_bytes = face->GetWidth() * 3;
849  const uint32 cube_row_bytes = cubemap->GetWidth() * 3;
850  const uint8* in = face->GetData()->GetData<uint8>();
851  uint8* out = cubemap->GetData()->GetMutableData<uint8>();
852  DCHECK(in);
853  DCHECK(out);
854  for (uint32 row = 0; row < face_height; ++row) {
855  const uint32 y = face_height - row - 1;
856  memcpy(&out[(y_offset + y) * cube_row_bytes + x_offset_bytes],
857  &in[y * face_row_bytes], face_row_bytes);
858  }
859 }
860 
862 static const std::string GetTextureData(const RendererPtr& renderer,
863  const HttpServer::QueryMap& args,
864  bool wait_for_completion) {
865  std::string data;
866  HttpServer::QueryMap::const_iterator id_it = args.find("id");
867  if (id_it != args.end()) {
868  if (GLuint id = static_cast<GLuint>(base::StringToInt32(id_it->second))) {
870  ResourceManager* manager = renderer->GetResourceManager();
871  RenderTextureCallback::RefPtr callback(
872  new RenderTextureCallback(renderer, wait_for_completion));
873  manager->RequestTextureImage(
874  id, std::bind(&RenderTextureCallback::Callback, callback.Get(), _1));
875  if (!wait_for_completion)
876  renderer->ProcessResourceInfoRequests();
877 
879  std::vector<TextureImageInfo> infos;
880  callback->WaitForCompletion(&infos);
881 
883  if (infos.size() && infos[0].images.size()) {
884  if (infos[0].images.size() == 1U) {
886  const std::vector<uint8> png_data = image::ConvertToExternalImageData(
887  infos[0].images[0], image::kPng, true);
889  std::string(png_data.begin(), png_data.end()));
890  } else {
892  DCHECK_EQ(6U, infos[0].images.size());
893  uint32 face_width = 0;
894  uint32 face_height = 0;
895  for (int i = 0; i < 6; ++i) {
896  face_width = std::max(face_width, infos[0].images[0]->GetWidth());
897  face_height =
898  std::max(face_height, infos[0].images[0]->GetHeight());
899  }
900 
902  ImagePtr cubemap(new Image);
903  const uint32 num_bytes = face_width * 3U * face_height * 4U * 3U;
904  base::DataContainerPtr cubemap_data =
905  base::DataContainer::CreateOverAllocated<uint8>(
906  num_bytes, NULL, cubemap->GetAllocator());
907  cubemap->Set(
908  Image::kRgb888, face_width * 3U, face_height * 4U, cubemap_data);
909  memset(cubemap_data->GetMutableData<uint8>(), 0, num_bytes);
910 
912  ----
915 
920  ----
922  ----
923  WriteFaceIntoCubeMap(face_width, 0U, infos[0].images[4], cubemap);
924  WriteFaceIntoCubeMap(0U, face_height, infos[0].images[0], cubemap);
925  WriteFaceIntoCubeMap(
926  face_width, face_height, infos[0].images[5], cubemap);
927  WriteFaceIntoCubeMap(
928  face_width * 2U, face_height, infos[0].images[3], cubemap);
929  WriteFaceIntoCubeMap(
930  face_width, face_height * 2U, infos[0].images[1], cubemap);
931  WriteFaceIntoCubeMap(
932  face_width, face_height * 3U, infos[0].images[2], cubemap);
933 
935  const std::vector<uint8> png_data =
938  std::string(png_data.begin(), png_data.end()));
939  }
940  }
941  }
942  }
943 
944  return data;
945 }
946 
947 } // anonymous namespace
948 
950 
955 
956 
958  : HttpServer::RequestHandler("/ion/resources"),
959  renderer_(renderer) {
960  IonRemoteResourcesRoot::RegisterAssetsOnce();
961 }
962 
964 
966  const std::string& path_in, const HttpServer::QueryMap& args,
967  std::string* content_type) {
968  const std::string path = path_in.empty() ? "index.html" : path_in;
969 
970  if (path == "buffer_data") {
971  return GetBufferData(renderer_, args);
972  } else if (path == "resources_by_type") {
973  *content_type = "application/json";
974  return GetResourceList(renderer_, args);
975  } else if (path == "texture_data") {
976  *content_type = "image/png";
977  return GetTextureData(
978  renderer_, args, args.find("nonblocking") == args.end());
979  } else {
980  const std::string& data = base::ZipAssetManager::GetFileData(
981  "ion/resources/" + path);
982  if (base::IsInvalidReference(data)) {
983  return std::string();
984  } else {
986  if (base::EndsWith(path, "html"))
987  *content_type = "text/html";
988  return data;
989  }
990  }
991 }
992 
993 } // namespace remote
994 } // namespace ion
995 
996 #endif
bool IsInvalidReference(const T &value)
IsInvalidReference() returns true if a passed const reference of type T has an address of InvalidRefe...
Definition: invalid.h:41
kShortTerm is used for objects that are very transient in nature, such as scratch memory used to comp...
Definition: allocator.h:36
const gfx::ImagePtr RenderTextureImage(const gfx::TexturePtr &texture, uint32 width, uint32 height, const gfx::RendererPtr &renderer, const base::AllocatorPtr &allocator)
Public functions.
Definition: renderutils.cc:258
const std::string & str
#define CHECK(expr)
Definition: logging.h:323
base::ReferentPtr< Image >::Type ImagePtr
Definition: image.h:29
#define DCHECK(expr)
Definition: logging.h:331
const std::string HandleRequest(const std::string &path, const HttpServer::QueryMap &args, std::string *content_type) override
The HandleRequest() function is passed the path (relative to its base path) of the file or directory ...
base::ReferentPtr< CubeMapTexture >::Type CubeMapTexturePtr
Convenience typedef for shared pointer to a CubeMapTexture.
#define GL_SAMPLER_EXTERNAL_OES
Definition: glheaders.h:912
ResourceCallback< gfx::ResourceManager::FramebufferInfo > FramebufferCallback
virtual const AllocatorPtr & GetAllocatorForLifetime(AllocationLifetime lifetime) const
Returns the correct Allocator to use to allocate memory with a specific lifetime. ...
Definition: allocator.cc:27
std::ostream & operator<<(std::ostream &os, const DateTime &dtime)
Definition: datetime.cc:361
std::vector< std::string > ION_API SplitString(const std::string &str, const std::string &delimiters)
Splits a string into a vector of substrings, given a set of delimiter characters (expressed as a stri...
Definition: stringutils.cc:187
static const std::string & GetFileData(const std::string &filename)
Returns the data of the passed filename if the manager contains it.
ResourceCallback< gfx::ResourceManager::TextureImageInfo > TextureImageCallback
SharedPtr< Allocator > AllocatorPtr
Definition: allocator.h:51
ResourceCallback< gfx::ResourceManager::ShaderInfo > ShaderCallback
ResourceHandler(const gfx::RendererPtr &renderer)
ResourceHandler functions.
std::string ION_API EscapeNewlines(const std::string &str)
Returns a string with all newlines replaced by "\\n".
Definition: stringutils.cc:152
std::string name
Definition: printer.cc:324
int32 ION_API StringToInt32(const std::string &str)
Extracts and returns an integral value from str.
Definition: stringutils.cc:328
ION_REGISTER_ASSETS(IonRemoteResourcesRoot)
Copyright 2016 Google Inc.
ResourceCallback< gfx::ResourceManager::TextureInfo > TextureCallback
ResourceCallback< gfx::ResourceManager::SamplerInfo > SamplerCallback
const std::string indent_
#define DCHECK_EQ(val1, val2)
Definition: logging.h:332
std::string ION_API MimeBase64EncodeString(const std::string &str)
Returns a mime base-64 encoded version of the passed string.
Definition: stringutils.cc:57
bool EndsWith(const std::string &target, const std::string &end)
Returns whether target ends with end.
Definition: stringutils.h:81
ResourceCallback< gfx::ResourceManager::ProgramInfo > ProgramCallback
const RendererPtr & renderer_
Renderer used to render images.
std::map< std::string, std::string > QueryMap
Definition: httpserver.h:35
ResourceCallback< gfx::ResourceManager::PlatformInfo > PlatformCallback
base::ReferentPtr< DataContainer >::Type DataContainerPtr
Definition: datacontainer.h:38
ResourceCallback< gfx::ResourceManager::ArrayInfo > ArrayCallback
std::string ReplaceString(const std::string &search, const std::string &from, const std::string &to)
Returns a string with all instances of from replaced with to.
Definition: stringutils.h:122
base::ReferentPtr< Renderer >::Type RendererPtr
Convenience typedef for shared pointer to a Renderer.
Definition: renderer.h:428
A SharedPtr is a smart shared pointer to an instance of some class that implements reference counting...
Definition: sharedptr.h:60
const std::vector< uint8 > ION_API ConvertToExternalImageData(const ImagePtr &image, ExternalImageFormat external_format, bool flip_vertically)
ResourceCallback< gfx::ResourceManager::BufferInfo > BufferCallback
base::ReferentPtr< Texture >::Type TexturePtr
Convenience typedef for shared pointer to a Texture.
Definition: texture.h:333
const size_t spaces_
const gfx::ImagePtr RenderCubeMapTextureFaceImage(const gfx::CubeMapTexturePtr &cubemap, gfx::CubeMapTexture::CubeFace face, uint32 width, uint32 height, const gfx::RendererPtr &renderer, const base::AllocatorPtr &allocator)
This is similar to RenderTextureImage(), but instead operates on one face of a CubeMapTexture.
Definition: renderutils.cc:267