Commit dbfb90d4 authored by dyen's avatar dyen Committed by Commit bot

Added Destroy() functions for GPUTimer and GPUTracer/GPUTrace.

BUG=467202
TEST=Shut down during gpu.device trace has no warnings.

Review URL: https://codereview.chromium.org/1018773002

Cr-Commit-Position: refs/heads/master@{#322304}
parent a51f1167
...@@ -3755,6 +3755,10 @@ void GLES2DecoderImpl::Destroy(bool have_context) { ...@@ -3755,6 +3755,10 @@ void GLES2DecoderImpl::Destroy(bool have_context) {
// by the context group. // by the context group.
async_pixel_transfer_manager_.reset(); async_pixel_transfer_manager_.reset();
// Destroy the GPU Tracer which may own some in process GPU Timings.
gpu_tracer_->Destroy(have_context);
gpu_tracer_ = NULL;
if (group_.get()) { if (group_.get()) {
framebuffer_manager()->RemoveObserver(this); framebuffer_manager()->RemoveObserver(this);
group_->Destroy(this, have_context); group_->Destroy(this, have_context);
......
...@@ -99,6 +99,12 @@ GPUTrace::GPUTrace(scoped_refptr<Outputter> outputter, ...@@ -99,6 +99,12 @@ GPUTrace::GPUTrace(scoped_refptr<Outputter> outputter,
GPUTrace::~GPUTrace() { GPUTrace::~GPUTrace() {
} }
void GPUTrace::Destroy(bool have_context) {
if (gpu_timer_.get()) {
gpu_timer_->Destroy(have_context);
}
}
void GPUTrace::Start(bool trace_service) { void GPUTrace::Start(bool trace_service) {
if (trace_service) { if (trace_service) {
outputter_->TraceServiceBegin(category_, name_); outputter_->TraceServiceBegin(category_, name_);
...@@ -152,6 +158,20 @@ GPUTracer::GPUTracer(gles2::GLES2Decoder* decoder) ...@@ -152,6 +158,20 @@ GPUTracer::GPUTracer(gles2::GLES2Decoder* decoder)
GPUTracer::~GPUTracer() { GPUTracer::~GPUTracer() {
} }
void GPUTracer::Destroy(bool have_context) {
for (int n = 0; n < NUM_TRACER_SOURCES; n++) {
for (size_t i = 0; i < markers_[n].size(); i++) {
TraceMarker& marker = markers_[n][i];
if (marker.trace_.get()) {
marker.trace_->Destroy(have_context);
marker.trace_ = 0;
}
}
}
ClearFinishedTraces(have_context);
}
bool GPUTracer::BeginDecoding() { bool GPUTracer::BeginDecoding() {
if (gpu_executing_) if (gpu_executing_)
return false; return false;
...@@ -194,10 +214,9 @@ bool GPUTracer::EndDecoding() { ...@@ -194,10 +214,9 @@ bool GPUTracer::EndDecoding() {
TraceMarker& marker = markers_[n][i]; TraceMarker& marker = markers_[n][i];
if (marker.trace_.get()) { if (marker.trace_.get()) {
marker.trace_->End(*gpu_trace_srv_category != 0); marker.trace_->End(*gpu_trace_srv_category != 0);
if (marker.trace_->IsEnabled())
traces_.push_back(marker.trace_);
markers_[n][i].trace_ = 0; finished_traces_.push_back(marker.trace_);
marker.trace_ = 0;
} }
} }
} }
...@@ -241,14 +260,14 @@ bool GPUTracer::End(GpuTracerSource source) { ...@@ -241,14 +260,14 @@ bool GPUTracer::End(GpuTracerSource source) {
// Pop last marker with matching 'source' // Pop last marker with matching 'source'
if (!markers_[source].empty()) { if (!markers_[source].empty()) {
if (IsTracing()) { scoped_refptr<GPUTrace> trace = markers_[source].back().trace_;
scoped_refptr<GPUTrace> trace = markers_[source].back().trace_; if (trace.get()) {
if (trace.get()) { if (IsTracing()) {
trace->End(*gpu_trace_srv_category != 0); trace->End(*gpu_trace_srv_category != 0);
if (trace->IsEnabled())
traces_.push_back(trace);
IssueProcessTask();
} }
finished_traces_.push_back(trace);
IssueProcessTask();
} }
markers_[source].pop_back(); markers_[source].pop_back();
...@@ -298,7 +317,7 @@ void GPUTracer::Process() { ...@@ -298,7 +317,7 @@ void GPUTracer::Process() {
void GPUTracer::ProcessTraces() { void GPUTracer::ProcessTraces() {
if (!gpu_timing_client_->IsAvailable()) { if (!gpu_timing_client_->IsAvailable()) {
traces_.clear(); ClearFinishedTraces(false);
return; return;
} }
...@@ -307,28 +326,42 @@ void GPUTracer::ProcessTraces() { ...@@ -307,28 +326,42 @@ void GPUTracer::ProcessTraces() {
// Make owning decoder's GL context current // Make owning decoder's GL context current
if (!decoder_->MakeCurrent()) { if (!decoder_->MakeCurrent()) {
// Skip subsequent GL calls if MakeCurrent fails // Skip subsequent GL calls if MakeCurrent fails
traces_.clear(); ClearFinishedTraces(false);
return; return;
} }
// Check if timers are still valid (e.g: a disjoint operation // Check if timers are still valid (e.g: a disjoint operation
// might have occurred.) // might have occurred.)
if (gpu_timing_client_->CheckAndResetTimerErrors()) if (gpu_timing_client_->CheckAndResetTimerErrors()) {
traces_.clear(); ClearFinishedTraces(true);
}
while (!traces_.empty() && traces_.front()->IsAvailable()) { while (!finished_traces_.empty()) {
traces_.front()->Process(); scoped_refptr<GPUTrace>& trace = finished_traces_.front();
traces_.pop_front(); if (trace->IsEnabled()) {
if (!finished_traces_.front()->IsAvailable())
break;
finished_traces_.front()->Process();
}
finished_traces_.front()->Destroy(true);
finished_traces_.pop_front();
} }
// Clear pending traces if there were are any errors // Clear pending traces if there were are any errors
GLenum err = glGetError(); GLenum err = glGetError();
if (err != GL_NO_ERROR) if (err != GL_NO_ERROR)
traces_.clear(); ClearFinishedTraces(true);
}
void GPUTracer::ClearFinishedTraces(bool have_context) {
while (!finished_traces_.empty()) {
finished_traces_.front()->Destroy(have_context);
finished_traces_.pop_front();
}
} }
void GPUTracer::IssueProcessTask() { void GPUTracer::IssueProcessTask() {
if (traces_.empty() || process_posted_) if (finished_traces_.empty() || process_posted_)
return; return;
process_posted_ = true; process_posted_ = true;
......
...@@ -56,6 +56,8 @@ class GPU_EXPORT GPUTracer ...@@ -56,6 +56,8 @@ class GPU_EXPORT GPUTracer
explicit GPUTracer(gles2::GLES2Decoder* decoder); explicit GPUTracer(gles2::GLES2Decoder* decoder);
virtual ~GPUTracer(); virtual ~GPUTracer();
void Destroy(bool have_context);
// Scheduled processing in decoder begins. // Scheduled processing in decoder begins.
bool BeginDecoding(); bool BeginDecoding();
...@@ -83,13 +85,14 @@ class GPU_EXPORT GPUTracer ...@@ -83,13 +85,14 @@ class GPU_EXPORT GPUTracer
void Process(); void Process();
void ProcessTraces(); void ProcessTraces();
void ClearFinishedTraces(bool have_context);
void IssueProcessTask(); void IssueProcessTask();
scoped_refptr<gfx::GPUTimingClient> gpu_timing_client_; scoped_refptr<gfx::GPUTimingClient> gpu_timing_client_;
scoped_refptr<Outputter> outputter_; scoped_refptr<Outputter> outputter_;
std::vector<TraceMarker> markers_[NUM_TRACER_SOURCES]; std::vector<TraceMarker> markers_[NUM_TRACER_SOURCES];
std::deque<scoped_refptr<GPUTrace> > traces_; std::deque<scoped_refptr<GPUTrace> > finished_traces_;
const unsigned char* gpu_trace_srv_category; const unsigned char* gpu_trace_srv_category;
const unsigned char* gpu_trace_dev_category; const unsigned char* gpu_trace_dev_category;
...@@ -155,6 +158,8 @@ class GPU_EXPORT GPUTrace ...@@ -155,6 +158,8 @@ class GPU_EXPORT GPUTrace
const std::string& name, const std::string& name,
const bool enabled); const bool enabled);
void Destroy(bool have_context);
void Start(bool trace_service); void Start(bool trace_service);
void End(bool tracing_service); void End(bool tracing_service);
bool IsAvailable(); bool IsAvailable();
......
...@@ -228,6 +228,7 @@ class BaseGpuTest : public GpuServiceTest { ...@@ -228,6 +228,7 @@ class BaseGpuTest : public GpuServiceTest {
void TearDown() override { void TearDown() override {
outputter_ref_ = NULL; outputter_ref_ = NULL;
gpu_timing_client_ = NULL;
gl_fake_queries_.Reset(); gl_fake_queries_.Reset();
GpuServiceTest::TearDown(); GpuServiceTest::TearDown();
...@@ -374,6 +375,9 @@ class BaseGpuTraceTest : public BaseGpuTest { ...@@ -374,6 +375,9 @@ class BaseGpuTraceTest : public BaseGpuTest {
// Proces should output expected Trace results to MockOutputter // Proces should output expected Trace results to MockOutputter
trace->Process(); trace->Process();
// Destroy trace after we are done.
trace->Destroy(true);
outputter_ref_ = NULL; outputter_ref_ = NULL;
} }
}; };
......
...@@ -96,6 +96,9 @@ Measurement MeasurementTimers::GetAsMeasurement(const std::string& name) { ...@@ -96,6 +96,9 @@ Measurement MeasurementTimers::GetAsMeasurement(const std::string& name) {
} }
MeasurementTimers::~MeasurementTimers() { MeasurementTimers::~MeasurementTimers() {
if (gpu_timer_.get()) {
gpu_timer_->Destroy(true);
}
} }
} // namespace gpu } // namespace gpu
...@@ -44,7 +44,16 @@ uint32_t GPUTiming::GetDisjointCount() { ...@@ -44,7 +44,16 @@ uint32_t GPUTiming::GetDisjointCount() {
} }
GPUTimer::~GPUTimer() { GPUTimer::~GPUTimer() {
glDeleteQueries(2, queries_); // Destroy() must be called before the destructor.
DCHECK(queries_[0] == 0);
DCHECK(queries_[1] == 0);
}
void GPUTimer::Destroy(bool have_context) {
if (have_context) {
glDeleteQueries(2, queries_);
}
memset(queries_, 0, sizeof(queries_));
} }
void GPUTimer::Start() { void GPUTimer::Start() {
......
...@@ -76,6 +76,10 @@ class GL_EXPORT GPUTimer { ...@@ -76,6 +76,10 @@ class GL_EXPORT GPUTimer {
public: public:
~GPUTimer(); ~GPUTimer();
// Destroy the timer object. This must be explicitly called before destroying
// this object.
void Destroy(bool have_context);
void Start(); void Start();
void End(); void End();
bool IsAvailable(); bool IsAvailable();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment