angle_platform_impl.cc 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. // Copyright 2015 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 "ui/gl/angle_platform_impl.h"
  5. #include "base/base64.h"
  6. #include "base/bind.h"
  7. #include "base/callback.h"
  8. #include "base/compiler_specific.h"
  9. #include "base/lazy_instance.h"
  10. #include "base/metrics/histogram.h"
  11. #include "base/metrics/histogram_functions.h"
  12. #include "base/task/thread_pool.h"
  13. #include "base/task/thread_pool/thread_pool_instance.h"
  14. #include "base/trace_event/trace_event.h"
  15. #include "third_party/angle/include/platform/PlatformMethods.h"
  16. #include "ui/gl/gl_bindings.h"
  17. namespace angle {
  18. namespace {
  19. ResetDisplayPlatformFunc g_angle_reset_platform = nullptr;
  20. double ANGLEPlatformImpl_currentTime(PlatformMethods* platform) {
  21. return base::Time::Now().ToDoubleT();
  22. }
  23. double ANGLEPlatformImpl_monotonicallyIncreasingTime(
  24. PlatformMethods* platform) {
  25. return (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF();
  26. }
  27. const unsigned char* ANGLEPlatformImpl_getTraceCategoryEnabledFlag(
  28. PlatformMethods* platform,
  29. const char* category_group) {
  30. return TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(category_group);
  31. }
  32. void ANGLEPlatformImpl_logError(PlatformMethods* platform,
  33. const char* errorMessage) {
  34. LOG(ERROR) << errorMessage;
  35. }
  36. void ANGLEPlatformImpl_logWarning(PlatformMethods* platform,
  37. const char* warningMessage) {
  38. LOG(WARNING) << warningMessage;
  39. }
  40. TraceEventHandle ANGLEPlatformImpl_addTraceEvent(
  41. PlatformMethods* platform,
  42. char phase,
  43. const unsigned char* category_group_enabled,
  44. const char* name,
  45. unsigned long long id,
  46. double timestamp,
  47. int num_args,
  48. const char** arg_names,
  49. const unsigned char* arg_types,
  50. const unsigned long long* arg_values,
  51. unsigned char flags) {
  52. base::TimeTicks timestamp_tt = base::TimeTicks() + base::Seconds(timestamp);
  53. base::trace_event::TraceArguments args(num_args, arg_names, arg_types,
  54. arg_values);
  55. base::trace_event::TraceEventHandle handle =
  56. TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP(
  57. phase, category_group_enabled, name,
  58. trace_event_internal::kGlobalScope, id, trace_event_internal::kNoId,
  59. base::PlatformThread::CurrentId(), timestamp_tt, &args, flags);
  60. TraceEventHandle result;
  61. memcpy(&result, &handle, sizeof(result));
  62. return result;
  63. }
  64. void ANGLEPlatformImpl_updateTraceEventDuration(
  65. PlatformMethods* platform,
  66. const unsigned char* category_group_enabled,
  67. const char* name,
  68. TraceEventHandle handle) {
  69. base::trace_event::TraceEventHandle trace_event_handle;
  70. memcpy(&trace_event_handle, &handle, sizeof(handle));
  71. TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(category_group_enabled, name,
  72. trace_event_handle);
  73. }
  74. void ANGLEPlatformImpl_histogramCustomCounts(PlatformMethods* platform,
  75. const char* name,
  76. int sample,
  77. int min,
  78. int max,
  79. int bucket_count) {
  80. // Copied from histogram macro, but without the static variable caching
  81. // the histogram because name is dynamic.
  82. base::HistogramBase* counter = base::Histogram::FactoryGet(
  83. name, min, max, bucket_count,
  84. base::HistogramBase::kUmaTargetedHistogramFlag);
  85. counter->Add(sample);
  86. }
  87. void ANGLEPlatformImpl_histogramEnumeration(PlatformMethods* platform,
  88. const char* name,
  89. int sample,
  90. int boundary_value) {
  91. // Copied from histogram macro, but without the static variable caching
  92. // the histogram because name is dynamic.
  93. base::HistogramBase* counter = base::LinearHistogram::FactoryGet(
  94. name, 1, boundary_value, boundary_value + 1,
  95. base::HistogramBase::kUmaTargetedHistogramFlag);
  96. counter->Add(sample);
  97. }
  98. void ANGLEPlatformImpl_histogramSparse(PlatformMethods* platform,
  99. const char* name,
  100. int sample) {
  101. base::UmaHistogramSparse(name, sample);
  102. }
  103. void ANGLEPlatformImpl_histogramBoolean(PlatformMethods* platform,
  104. const char* name,
  105. bool sample) {
  106. ANGLEPlatformImpl_histogramEnumeration(platform, name, sample ? 1 : 0, 2);
  107. }
  108. NO_SANITIZE("cfi-icall")
  109. void AnglePlatformImpl_runWorkerTask(PostWorkerTaskCallback callback, void* user_data) {
  110. TRACE_EVENT0("toplevel", "ANGLEPlatformImpl::RunWorkerTask");
  111. callback(user_data);
  112. }
  113. void ANGLEPlatformImpl_postWorkerTask(PlatformMethods* platform,
  114. PostWorkerTaskCallback callback,
  115. void* user_data) {
  116. base::ThreadPool::PostTask(
  117. FROM_HERE, {base::TaskPriority::USER_VISIBLE},
  118. base::BindOnce(&AnglePlatformImpl_runWorkerTask, callback, user_data));
  119. }
  120. } // anonymous namespace
  121. NO_SANITIZE("cfi-icall")
  122. bool InitializePlatform(EGLDisplay display) {
  123. GetDisplayPlatformFunc angle_get_platform =
  124. reinterpret_cast<GetDisplayPlatformFunc>(
  125. eglGetProcAddress("ANGLEGetDisplayPlatform"));
  126. if (!angle_get_platform)
  127. return false;
  128. // Save the pointer to the destroy function here to avoid crash.
  129. g_angle_reset_platform = reinterpret_cast<ResetDisplayPlatformFunc>(
  130. eglGetProcAddress("ANGLEResetDisplayPlatform"));
  131. PlatformMethods* platformMethods = nullptr;
  132. if (!angle_get_platform(static_cast<EGLDisplayType>(display),
  133. g_PlatformMethodNames, g_NumPlatformMethods, nullptr,
  134. &platformMethods))
  135. return false;
  136. platformMethods->currentTime = ANGLEPlatformImpl_currentTime;
  137. platformMethods->addTraceEvent = ANGLEPlatformImpl_addTraceEvent;
  138. platformMethods->getTraceCategoryEnabledFlag =
  139. ANGLEPlatformImpl_getTraceCategoryEnabledFlag;
  140. platformMethods->histogramBoolean = ANGLEPlatformImpl_histogramBoolean;
  141. platformMethods->histogramCustomCounts =
  142. ANGLEPlatformImpl_histogramCustomCounts;
  143. platformMethods->histogramEnumeration =
  144. ANGLEPlatformImpl_histogramEnumeration;
  145. platformMethods->histogramSparse = ANGLEPlatformImpl_histogramSparse;
  146. platformMethods->logError = ANGLEPlatformImpl_logError;
  147. platformMethods->logWarning = ANGLEPlatformImpl_logWarning;
  148. platformMethods->monotonicallyIncreasingTime =
  149. ANGLEPlatformImpl_monotonicallyIncreasingTime;
  150. platformMethods->updateTraceEventDuration =
  151. ANGLEPlatformImpl_updateTraceEventDuration;
  152. // Initialize the delegate to allow posting tasks in the Chromium thread pool.
  153. // The thread pool is not available in some unittests.
  154. if (base::ThreadPoolInstance::Get())
  155. platformMethods->postWorkerTask = ANGLEPlatformImpl_postWorkerTask;
  156. return true;
  157. }
  158. NO_SANITIZE("cfi-icall")
  159. void ResetPlatform(EGLDisplay display) {
  160. if (!g_angle_reset_platform)
  161. return;
  162. g_angle_reset_platform(static_cast<EGLDisplayType>(display));
  163. }
  164. } // namespace angle