Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(34)

Unified Diff: services/gfx/compositor/backend/gpu_rasterizer.cc

Issue 1995873002: Mozart: Improve tracing and backpressure. (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: address review comments Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: services/gfx/compositor/backend/gpu_rasterizer.cc
diff --git a/services/gfx/compositor/backend/gpu_rasterizer.cc b/services/gfx/compositor/backend/gpu_rasterizer.cc
index 4625490a7f2f32916705af021074a5f0dfb9e698..85c555360abadc96568e78fb0265f365edcf91d8 100644
--- a/services/gfx/compositor/backend/gpu_rasterizer.cc
+++ b/services/gfx/compositor/backend/gpu_rasterizer.cc
@@ -13,7 +13,6 @@
#include <MGL/mgl.h>
#include <MGL/mgl_echo.h>
#include <MGL/mgl_onscreen.h>
-#include <MGL/mgl_signal_sync_point.h>
#include "base/bind.h"
#include "base/location.h"
@@ -21,29 +20,27 @@
#include "base/message_loop/message_loop.h"
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
-#include "services/gfx/compositor/backend/vsync_scheduler.h"
#include "services/gfx/compositor/render/render_frame.h"
namespace compositor {
namespace {
+// Timeout for receiving initial viewport parameters from the GPU service.
constexpr int64_t kViewportParameterTimeoutMs = 1000;
+
+// Default vsync interval when the GPU service failed to provide viewport
+// parameters promptly.
constexpr int64_t kDefaultVsyncIntervalUs = 100000; // deliberately sluggish
}
GpuRasterizer::GpuRasterizer(mojo::ContextProviderPtr context_provider,
- const scoped_refptr<VsyncScheduler>& scheduler,
- const scoped_refptr<base::TaskRunner>& task_runner,
- const base::Closure& error_callback)
+ Callbacks* callbacks)
: context_provider_(context_provider.Pass()),
- scheduler_(scheduler),
- task_runner_(task_runner),
- error_callback_(error_callback),
+ callbacks_(callbacks),
viewport_parameter_listener_binding_(this),
viewport_parameter_timeout_(false, false),
weak_ptr_factory_(this) {
DCHECK(context_provider_);
- DCHECK(scheduler_);
- DCHECK(task_runner_);
+ DCHECK(callbacks_);
context_provider_.set_connection_error_handler(
base::Bind(&GpuRasterizer::OnContextProviderConnectionError,
@@ -76,12 +73,13 @@ void GpuRasterizer::InitContext(
if (!command_buffer) {
LOG(ERROR) << "Could not create GL context.";
- PostErrorCallback();
+ callbacks_->OnRasterizerError();
return;
}
gl_context_ = mojo::GLContext::CreateFromCommandBuffer(
mojo::CommandBufferPtr::Create(std::move(command_buffer)));
+ DCHECK(!gl_context_->is_lost());
gl_context_->AddObserver(this);
ganesh_context_ = new mojo::skia::GaneshContext(gl_context_);
@@ -94,19 +92,20 @@ void GpuRasterizer::InitContext(
base::Bind(&GpuRasterizer::OnViewportParameterTimeout,
base::Unretained(this)));
}
-
- if (frame_)
- Draw();
}
void GpuRasterizer::AbandonContext() {
- if (gl_context_)
- scheduler_->Stop();
-
if (viewport_parameter_listener_binding_.is_bound()) {
viewport_parameter_timeout_.Stop();
viewport_parameter_listener_binding_.Close();
}
+
+ if (ready_) {
+ while (frames_in_progress_)
+ DrawFinished(false /*presented*/);
+ ready_ = false;
+ callbacks_->OnRasterizerSuspended();
+ }
}
void GpuRasterizer::DestroyContext() {
@@ -124,15 +123,14 @@ void GpuRasterizer::DestroyContext() {
void GpuRasterizer::OnContextProviderConnectionError() {
LOG(ERROR) << "Context provider connection lost.";
- PostErrorCallback();
+
+ callbacks_->OnRasterizerError();
}
void GpuRasterizer::OnContextLost() {
LOG(WARNING) << "GL context lost!";
AbandonContext();
- frames_pending_ = 0u;
-
base::MessageLoop::current()->PostTask(
FROM_HERE, base::Bind(&GpuRasterizer::RecreateContextAfterLoss,
weak_ptr_factory_.GetWeakPtr()));
@@ -167,71 +165,33 @@ void GpuRasterizer::OnVSyncParametersUpdated(int64_t timebase,
}
vsync_timebase_ = timebase;
vsync_interval_ = interval;
-
- if (gl_context_ && !gl_context_->is_lost())
- ApplyViewportParameters();
+ ApplyViewportParameters();
}
void GpuRasterizer::ApplyViewportParameters() {
DCHECK(have_viewport_parameters_);
- DCHECK(gl_context_);
- // TODO(jeffbrown): This shouldn't be hardcoded.
- // Need to do some real tuning and possibly determine values adaptively.
- int64_t update_phase = -vsync_interval_;
- int64_t snapshot_phase = -vsync_interval_ / 6;
- int64_t presentation_phase = vsync_interval_;
- if (!scheduler_->Start(vsync_timebase_, vsync_interval_, update_phase,
- snapshot_phase, presentation_phase)) {
- LOG(ERROR) << "Received invalid vsync parameters: timebase="
- << vsync_timebase_ << ", interval=" << vsync_interval_;
- PostErrorCallback();
+ if (gl_context_ && !gl_context_->is_lost()) {
+ ready_ = true;
+ callbacks_->OnRasterizerReady(vsync_timebase_, vsync_interval_);
}
}
-constexpr uint32_t kMaxFramesPending = 2;
-
-void GpuRasterizer::SubmitFrame(const scoped_refptr<RenderFrame>& frame,
- const FrameCallback& frame_callback) {
- TRACE_EVENT0("gfx", "GpuRasterizer::SubmitFrame");
+void GpuRasterizer::DrawFrame(const scoped_refptr<RenderFrame>& frame) {
DCHECK(frame);
-
- if (frame_ && !frame_callback_.is_null())
- frame_callback_.Run(false); // frame discarded
-
- frame_ = frame;
- frame_callback_ = frame_callback;
-
- if (gl_context_ && !gl_context_->is_lost()) {
- if (frames_pending_ == kMaxFramesPending) {
- TRACE_EVENT_INSTANT0("gfx", "GpuRasterizer dropping",
- TRACE_EVENT_SCOPE_THREAD);
- LOG(ERROR) << "too many frames pending, dropping";
- frame_callback_.Run(false);
- return;
- }
- Draw();
- } else
- frame_callback_.Run(false);
-}
-
-static void DidEcho(void* context) {
- TRACE_EVENT_ASYNC_END0("gfx", "SwapBuffers Echo", context);
- auto cb = static_cast<base::Closure*>(context);
- cb->Run();
- delete cb;
-}
-
-void GpuRasterizer::Draw() {
- TRACE_EVENT0("gfx", "GpuRasterizer::Draw");
+ DCHECK(ready_);
DCHECK(gl_context_);
+ DCHECK(!gl_context_->is_lost());
DCHECK(ganesh_context_);
- DCHECK(frame_);
+
+ uint32_t frame_number = total_frames_++;
+ frames_in_progress_++;
+ TRACE_EVENT1("gfx", "GpuRasterizer::DrawFrame", "num", frame_number);
mojo::GLContext::Scope gl_scope(gl_context_);
// Update the viewport.
- const SkIRect& viewport = frame_->viewport();
+ const SkIRect& viewport = frame->viewport();
bool stale_surface = false;
if (!ganesh_surface_ ||
ganesh_surface_->surface()->width() != viewport.width() ||
@@ -241,7 +201,7 @@ void GpuRasterizer::Draw() {
stale_surface = true;
}
- // Paint the frame.
+ // Draw the frame content.
{
mojo::skia::GaneshContext::Scope ganesh_scope(ganesh_context_);
@@ -250,38 +210,36 @@ void GpuRasterizer::Draw() {
new mojo::skia::GaneshFramebufferSurface(ganesh_scope));
}
- frame_->Paint(ganesh_surface_->canvas());
+ frame->Draw(ganesh_surface_->canvas());
}
- // Swap buffers and listen for completion.
- // TODO: Investigate using |MGLSignalSyncPoint| to wait for completion.
+ // Swap buffers.
{
TRACE_EVENT0("gfx", "MGLSwapBuffers");
MGLSwapBuffers();
}
- base::Closure* echo_callback = new base::Closure(
- base::Bind(&GpuRasterizer::DidEchoCallback,
- weak_ptr_factory_.GetWeakPtr(), frame_callback_));
- frame_callback_.Reset();
- TRACE_EVENT_ASYNC_BEGIN0("gfx", "SwapBuffers Echo", echo_callback);
- MGLEcho(DidEcho, echo_callback);
- frames_pending_++;
- TRACE_COUNTER1("gfx", "GpuRasterizer::frames_pending_", frames_pending_);
+
+ // Listen for completion.
+ TRACE_EVENT_ASYNC_BEGIN0("gfx", "MGLEcho", frame_number);
+ MGLEcho(&GpuRasterizer::OnMGLEchoReply, this);
}
-void GpuRasterizer::DidEchoCallback(FrameCallback frame_callback) {
- frames_pending_--;
- TRACE_COUNTER1("gfx", "GpuRasterizer::frames_pending_", frames_pending_);
- TRACE_EVENT0("gfx", "GpuRasterizer::DidEchoCallback");
- // Signal pending callback for backpressure.
- if (!frame_callback.is_null()) {
- frame_callback.Run(true);
- frame_callback.Reset();
- }
+void GpuRasterizer::DrawFinished(bool presented) {
+ DCHECK(frames_in_progress_);
+
+ uint32_t frame_number = total_frames_ - frames_in_progress_;
+ frames_in_progress_--;
+ TRACE_EVENT2("gfx", "GpuRasterizer::DrawFinished", "num", frame_number,
+ "presented", presented);
+ TRACE_EVENT_ASYNC_END0("gfx", "MGLEcho", frame_number);
+
+ callbacks_->OnRasterizerFinishedDraw(presented);
}
-void GpuRasterizer::PostErrorCallback() {
- task_runner_->PostTask(FROM_HERE, error_callback_);
+void GpuRasterizer::OnMGLEchoReply(void* context) {
+ auto rasterizer = static_cast<GpuRasterizer*>(context);
+ if (rasterizer->ready_)
+ rasterizer->DrawFinished(true /*presented*/);
}
} // namespace compositor

Powered by Google App Engine
This is Rietveld 408576698