Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 511544f2 authored by Steven Thomas's avatar Steven Thomas Committed by Android (Google) Code Review
Browse files

Merge "Fix query management in GpuProfiler" into oc-dev

parents 1ab06328 28f85d6a
Loading
Loading
Loading
Loading
+50 −2
Original line number Diff line number Diff line
@@ -7,6 +7,12 @@
namespace android {
namespace dvr {

namespace {

constexpr int kMaxPendingQueries = 32;

}  // anonynmous namespace

static int64_t AdjustTimerQueryToNs(int64_t gpu_time) { return gpu_time; }

void GpuProfiler::TimerData::reset() {
@@ -21,6 +27,7 @@ void GpuProfiler::TimerData::print(const char* name) const {

// Enter a scope, records the timestamp for later matching with leave.
void GpuProfiler::TimerData::enter(int64_t timestamp_ns) {
  entered = true;
  enter_timestamp_ns = timestamp_ns;
}

@@ -28,6 +35,15 @@ void GpuProfiler::TimerData::enter(int64_t timestamp_ns) {
void GpuProfiler::TimerData::leave(int64_t timestamp_ns, const char* name,
                                   std::weak_ptr<int64_t> duration_ns,
                                   int print_period) {
  if (!entered) {
    // We got the leave event but are missing the enter. This can happen if
    // OnPendingQueryOverflow() is called, or if the calls to enter()/leave()
    // aren't properly balanced. Ignore the call but print a warning.
    ALOGW("Ignoring GpuProfiler::TimerData::leave event with no enter event");
    return;
  }
  entered = false;

  int64_t elapsed = timestamp_ns - enter_timestamp_ns;
  if (elapsed > 1000 * 1000 * 1000) {
    // More than one second, drop it as invalid data.
@@ -50,12 +66,12 @@ GpuProfiler* GpuProfiler::Get() {

GpuProfiler::GpuProfiler()
    : enable_gpu_tracing_(true),
      has_gl_context_(false),
      sync_with_cpu_time_(false),
      gl_timer_offset_ns_(0) {
  SyncGlTimebase();
}

GpuProfiler::~GpuProfiler() {}
GpuProfiler::~GpuProfiler() { Clear(); }

bool GpuProfiler::IsGpuProfilingSupported() const {
  // TODO(jbates) check for GL_EXT_disjoint_timer_query
@@ -63,6 +79,9 @@ bool GpuProfiler::IsGpuProfilingSupported() const {
}

GLuint GpuProfiler::TryAllocateGlQueryId() {
  if (pending_gpu_queries_.size() >= kMaxPendingQueries)
    OnPendingQueryOverflow();

  GLuint query_id = 0;
  if (gl_timer_query_id_pool_.empty()) {
    glGenQueries(1, &query_id);
@@ -95,6 +114,35 @@ void GpuProfiler::LeaveGlScope(const char* scope_name,
  }
}

void GpuProfiler::OnGlContextCreated() {
  has_gl_context_ = true;
  gl_timer_offset_ns_ = 0;
  SyncGlTimebase();
}

void GpuProfiler::OnGlContextDestroyed() {
  has_gl_context_ = false;
  Clear();
}

void GpuProfiler::Clear() {
  events_.clear();
  for (auto& query : pending_gpu_queries_)
    glDeleteQueries(1, &query.query_id);
  pending_gpu_queries_.clear();
  while (!gl_timer_query_id_pool_.empty()) {
    GLuint id = gl_timer_query_id_pool_.top();
    gl_timer_query_id_pool_.pop();
    glDeleteQueries(1, &id);
  }
}

void GpuProfiler::OnPendingQueryOverflow() {
  ALOGW("Reached limit of %d pending queries in GpuProfiler."
        " Clearing all queries.", kMaxPendingQueries);
  Clear();
}

void GpuProfiler::SyncGlTimebase() {
  if (!sync_with_cpu_time_) {
    return;
+22 −1
Original line number Diff line number Diff line
@@ -38,7 +38,7 @@ class GpuProfiler {
  // one of the TRACE_GPU* macros defined below.
  void SetEnableGpuTracing(bool enabled) { enable_gpu_tracing_ = enabled; }

  bool enabled() const { return enable_gpu_tracing_; }
  bool enabled() const { return enable_gpu_tracing_ && has_gl_context_; }

  // Attempt to keep the GPU times in sync with CPU times.
  void SetEnableSyncCpuTime(bool enabled) { sync_with_cpu_time_ = enabled; }
@@ -62,6 +62,14 @@ class GpuProfiler {
  void LeaveGlScope(const char* scope_name, std::weak_ptr<int64_t> duration_ns,
                    int print_period);

  // Must be called when the GL context is created. The GpuProfiler will be
  // inactive until this is called.
  void OnGlContextCreated();

  // Must be called before the GL context is destroyed. The GpuProfiler will be
  // inactive until a call to OnGlContextCreated().
  void OnGlContextDestroyed();

 private:
  // Data to queue the pending GPU timer queries that need to be polled
  // for completion.
@@ -105,11 +113,20 @@ class GpuProfiler {
    void leave(int64_t timestamp_ns, const char* name,
               std::weak_ptr<int64_t> duration_ns, int print_period);

    bool entered = false;
    int64_t total_elapsed_ns = 0;
    int64_t enter_timestamp_ns = 0;
    int num_events = 0;
  };

  // Clear out events and free GL resources.
  void Clear();

  // Called when we detect that we've overflowed the pending query queue. This
  // shouldn't occur in practice, and probably indicates some internal
  // mismanagement of the gl query objects.
  void OnPendingQueryOverflow();

  // Synchronises the GL timebase with the CallTraceManager timebase.
  void SyncGlTimebase();

@@ -119,6 +136,10 @@ class GpuProfiler {
  // Setting for enabling GPU tracing.
  bool enable_gpu_tracing_;

  // True if we have a GL context, false otherwise. When the GpuProfiler is
  // first created we assume no GL context.
  bool has_gl_context_;

  // Setting for synchronizing GPU timestamps with CPU time.
  bool sync_with_cpu_time_;

+2 −0
Original line number Diff line number Diff line
@@ -403,6 +403,7 @@ bool Compositor::InitializeEGL() {
  }

  load_gl_extensions();
  GpuProfiler::Get()->OnGlContextCreated();

  glEnable(BINNING_CONTROL_HINT_QCOM);
  glHint(BINNING_CONTROL_HINT_QCOM, RENDER_DIRECT_TO_FRAMEBUFFER_QCOM);
@@ -438,6 +439,7 @@ void Compositor::Shutdown() {
  eds_renderer_.reset();

  if (context_) {
    GpuProfiler::Get()->OnGlContextDestroyed();
    eglDestroyContext(display_, context_);
    context_ = 0;
  }