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

Unified Diff: mojo/ui/choreographer.cc

Issue 1556803002: Add helpers for creating UI components. (Closed) Base URL: git@github.com:domokit/mojo.git@moz-13
Patch Set: address feedback Created 4 years, 11 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
« no previous file with comments | « mojo/ui/choreographer.h ('k') | mojo/ui/content_viewer_app.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: mojo/ui/choreographer.cc
diff --git a/mojo/ui/choreographer.cc b/mojo/ui/choreographer.cc
new file mode 100644
index 0000000000000000000000000000000000000000..7ea295b682aecc1d9c44c15d884aaa9f38c3d973
--- /dev/null
+++ b/mojo/ui/choreographer.cc
@@ -0,0 +1,119 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "mojo/ui/choreographer.h"
+
+#include "base/bind.h"
+#include "base/logging.h"
+#include "mojo/public/cpp/system/functions.h"
+
+namespace mojo {
+namespace ui {
+
+Choreographer::Choreographer(mojo::gfx::composition::Scene* scene,
+ ChoreographerDelegate* delegate)
+ : delegate_(delegate) {
+ DCHECK(delegate_);
+ scene->GetScheduler(mojo::GetProxy(&scene_scheduler_));
+}
+
+Choreographer::Choreographer(
+ mojo::gfx::composition::SceneSchedulerPtr scene_scheduler,
+ ChoreographerDelegate* delegate)
+ : scene_scheduler_(scene_scheduler.Pass()), delegate_(delegate) {
+ DCHECK(scene_scheduler_);
+ DCHECK(delegate_);
+}
+
+Choreographer::~Choreographer() {}
+
+void Choreographer::ScheduleDraw() {
+ if (!draw_scheduled_) {
+ draw_scheduled_ = true;
+ ScheduleFrame();
+ }
+}
+
+void Choreographer::ScheduleFrame() {
+ if (!frame_scheduled_) {
+ frame_scheduled_ = true;
+ scene_scheduler_->ScheduleFrame(
+ base::Bind(&Choreographer::DoFrame, base::Unretained(this)));
+ }
+}
+
+void Choreographer::DoFrame(mojo::gfx::composition::FrameInfoPtr frame_info) {
+ DCHECK(frame_info);
+ DCHECK(frame_scheduled_);
+ frame_scheduled_ = false;
+
+ if (draw_scheduled_) {
+ draw_scheduled_ = false;
+
+ // To reduce latency and jank, anticipate the next frame to be drawn by
+ // scheduling it early.
+ //
+ // TODO(jeffbrown): Reenable this once issue #604 is fixed. Unfortunately
+ // this exacerbates starvation issues in the Mojo message pump.
+ // ScheduleFrame();
+
+ // Ensure frame info is sane since it comes from another service.
+ // TODO(jeffbrown): Would be better to report an error to the client
+ // who can shut things down if needed.
+ MojoTimeTicks now = MojoGetTimeTicksNow();
+ if (frame_info->frame_time > now) {
+ LOG(WARNING) << "Frame time is in the future: frame_time="
+ << frame_info->frame_time << ", now=" << now;
+ frame_info->frame_time = now;
+ }
+ if (frame_info->frame_deadline < frame_info->frame_time) {
+ LOG(WARNING)
+ << "Frame deadline is earlier than frame time: frame_deadline="
+ << frame_info->frame_deadline
+ << ", frame_time=" << frame_info->frame_time << ", now=" << now;
+ frame_info->frame_deadline = frame_info->frame_time;
+ }
+ if (frame_info->presentation_time < frame_info->frame_deadline) {
+ LOG(WARNING) << "Presentation time is earlier than frame deadline: "
+ "presentation_time="
+ << frame_info->presentation_time
+ << ", frame_deadline=" << frame_info->frame_deadline
+ << ", now=" << now;
+ frame_info->presentation_time = frame_info->frame_deadline;
+ }
+
+ // Compensate for significant lag by adjusting the frame time if needed
+ // to step past skipped frames.
+ uint64_t lag = now - frame_info->frame_time;
+ if (frame_info->frame_interval > 0u && lag > frame_info->frame_interval) {
+ uint64_t offset = lag % frame_info->frame_interval;
+ uint64_t adjustment = now - offset - frame_info->frame_time;
+ frame_info->frame_time = now - offset;
+ frame_info->frame_deadline += adjustment;
+ frame_info->presentation_time += adjustment;
+
+ // Jank warning.
+ // TODO(jeffbrown): Suppress this once we're happy with things.
+ LOG(WARNING) << "Missed " << frame_info->frame_interval
+ << " us frame deadline by " << lag << " us, skipping "
+ << (lag / frame_info->frame_interval) << " frames";
+ }
+
+ // Ensure frame time isn't going backwards, just in case the compositor's
+ // timing is seriously broken.
+ base::TimeDelta time_delta;
+ if (last_frame_info_) {
+ DCHECK(frame_info->frame_time >= last_frame_info_->frame_time);
+ time_delta = base::TimeDelta::FromMicroseconds(
+ frame_info->frame_time - last_frame_info_->frame_time);
+ }
+
+ // Invoke the callback.
+ last_frame_info_ = frame_info.Pass();
+ delegate_->OnDraw(*last_frame_info_, time_delta);
+ }
+}
+
+} // namespace ui
+} // namespace mojo
« no previous file with comments | « mojo/ui/choreographer.h ('k') | mojo/ui/content_viewer_app.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698