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

Side by Side Diff: ash/laser/laser_pointer_view.cc

Issue 2745953002: ash: Add basic prediction code to the laser pointer. (Closed)
Patch Set: missing include and minor cleanup Created 3 years, 9 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 unified diff | Download patch
« ash/common/ash_switches.cc ('K') | « ash/laser/laser_pointer_view.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ash/laser/laser_pointer_view.h" 5 #include "ash/laser/laser_pointer_view.h"
6 6
7 #include <GLES2/gl2.h> 7 #include <GLES2/gl2.h>
8 #include <GLES2/gl2ext.h> 8 #include <GLES2/gl2ext.h>
9 #include <GLES2/gl2extchromium.h> 9 #include <GLES2/gl2extchromium.h>
10 10
11 #include <algorithm>
12 #include <array>
13 #include <cmath>
11 #include <memory> 14 #include <memory>
12 15
13 #include "ash/laser/laser_pointer_points.h" 16 #include "ash/laser/laser_pointer_points.h"
14 #include "ash/laser/laser_segment_utils.h" 17 #include "ash/laser/laser_segment_utils.h"
15 #include "ash/public/cpp/shell_window_ids.h" 18 #include "ash/public/cpp/shell_window_ids.h"
16 #include "ash/shell.h" 19 #include "ash/shell.h"
20 #include "base/containers/adapters.h"
17 #include "base/threading/thread_task_runner_handle.h" 21 #include "base/threading/thread_task_runner_handle.h"
18 #include "base/timer/timer.h" 22 #include "base/timer/timer.h"
19 #include "base/trace_event/trace_event.h" 23 #include "base/trace_event/trace_event.h"
20 #include "cc/output/context_provider.h" 24 #include "cc/output/context_provider.h"
21 #include "cc/quads/texture_draw_quad.h" 25 #include "cc/quads/texture_draw_quad.h"
22 #include "cc/resources/transferable_resource.h" 26 #include "cc/resources/transferable_resource.h"
23 #include "cc/surfaces/surface.h" 27 #include "cc/surfaces/surface.h"
24 #include "cc/surfaces/surface_manager.h" 28 #include "cc/surfaces/surface_manager.h"
25 #include "gpu/command_buffer/client/context_support.h" 29 #include "gpu/command_buffer/client/context_support.h"
26 #include "gpu/command_buffer/client/gles2_interface.h" 30 #include "gpu/command_buffer/client/gles2_interface.h"
27 #include "gpu/command_buffer/client/gpu_memory_buffer_manager.h" 31 #include "gpu/command_buffer/client/gpu_memory_buffer_manager.h"
28 #include "third_party/skia/include/core/SkColor.h" 32 #include "third_party/skia/include/core/SkColor.h"
29 #include "third_party/skia/include/core/SkTypes.h" 33 #include "third_party/skia/include/core/SkTypes.h"
30 #include "ui/aura/env.h" 34 #include "ui/aura/env.h"
31 #include "ui/aura/window.h" 35 #include "ui/aura/window.h"
32 #include "ui/display/display.h" 36 #include "ui/display/display.h"
33 #include "ui/display/screen.h" 37 #include "ui/display/screen.h"
38 #include "ui/events/base_event_utils.h"
34 #include "ui/events/event.h" 39 #include "ui/events/event.h"
35 #include "ui/gfx/canvas.h" 40 #include "ui/gfx/canvas.h"
36 #include "ui/gfx/gpu_memory_buffer.h" 41 #include "ui/gfx/gpu_memory_buffer.h"
37 #include "ui/views/widget/widget.h" 42 #include "ui/views/widget/widget.h"
38 43
39 namespace ash { 44 namespace ash {
40 namespace { 45 namespace {
41 46
42 // Variables for rendering the laser. Radius in DIP. 47 // Variables for rendering the laser. Radius in DIP.
43 const float kPointInitialRadius = 5.0f; 48 const float kPointInitialRadius = 5.0f;
44 const float kPointFinalRadius = 0.25f; 49 const float kPointFinalRadius = 0.25f;
45 const int kPointInitialOpacity = 200; 50 const int kPointInitialOpacity = 200;
46 const int kPointFinalOpacity = 10; 51 const int kPointFinalOpacity = 10;
47 const SkColor kPointColor = SkColorSetRGB(255, 0, 0); 52 const SkColor kPointColor = SkColorSetRGB(255, 0, 0);
53 // Change this to a debug prediction code.
Daniel Erat 2017/03/16 16:50:55 i don't quite understand this comment. would somet
reveman 2017/03/16 18:00:24 oh, the "a" shouldn't have been in that sentence.
54 const SkColor kPredictionPointColor = kPointColor;
48 55
49 float DistanceBetweenPoints(const gfx::PointF& point1, 56 float DistanceBetweenPoints(const gfx::PointF& point1,
50 const gfx::PointF& point2) { 57 const gfx::PointF& point2) {
51 return (point1 - point2).Length(); 58 return (point1 - point2).Length();
52 } 59 }
53 60
54 float LinearInterpolate(float initial_value, 61 float LinearInterpolate(float initial_value,
55 float final_value, 62 float final_value,
56 float progress) { 63 float progress) {
57 return initial_value + (final_value - initial_value) * progress; 64 return initial_value + (final_value - initial_value) * progress;
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 } 196 }
190 } 197 }
191 scoped_refptr<cc::ContextProvider> context_provider; 198 scoped_refptr<cc::ContextProvider> context_provider;
192 uint32_t texture = 0; 199 uint32_t texture = 0;
193 uint32_t image = 0; 200 uint32_t image = 0;
194 gpu::Mailbox mailbox; 201 gpu::Mailbox mailbox;
195 }; 202 };
196 203
197 // LaserPointerView 204 // LaserPointerView
198 LaserPointerView::LaserPointerView(base::TimeDelta life_duration, 205 LaserPointerView::LaserPointerView(base::TimeDelta life_duration,
206 base::TimeDelta presentation_delay,
199 aura::Window* root_window) 207 aura::Window* root_window)
200 : laser_points_(life_duration), 208 : laser_points_(life_duration),
209 predicted_laser_points_(life_duration),
210 presentation_delay_(presentation_delay),
201 frame_sink_id_(aura::Env::GetInstance() 211 frame_sink_id_(aura::Env::GetInstance()
202 ->context_factory_private() 212 ->context_factory_private()
203 ->AllocateFrameSinkId()), 213 ->AllocateFrameSinkId()),
204 frame_sink_support_(this, 214 frame_sink_support_(this,
205 aura::Env::GetInstance() 215 aura::Env::GetInstance()
206 ->context_factory_private() 216 ->context_factory_private()
207 ->GetSurfaceManager(), 217 ->GetSurfaceManager(),
208 frame_sink_id_, 218 frame_sink_id_,
209 false /* is_root */, 219 false /* is_root */,
210 true /* handles_frame_sink_id_invalidation */, 220 true /* handles_frame_sink_id_invalidation */,
(...skipping 24 matching lines...) Expand all
235 245
236 LaserPointerView::~LaserPointerView() { 246 LaserPointerView::~LaserPointerView() {
237 // Make sure GPU memory buffer is unmapped before being destroyed. 247 // Make sure GPU memory buffer is unmapped before being destroyed.
238 if (gpu_memory_buffer_) 248 if (gpu_memory_buffer_)
239 gpu_memory_buffer_->Unmap(); 249 gpu_memory_buffer_->Unmap();
240 } 250 }
241 251
242 void LaserPointerView::Stop() { 252 void LaserPointerView::Stop() {
243 buffer_damage_rect_.Union(GetBoundingBox()); 253 buffer_damage_rect_.Union(GetBoundingBox());
244 laser_points_.Clear(); 254 laser_points_.Clear();
255 predicted_laser_points_.Clear();
245 OnPointsUpdated(); 256 OnPointsUpdated();
246 } 257 }
247 258
248 void LaserPointerView::AddNewPoint(const gfx::PointF& new_point) { 259 void LaserPointerView::AddNewPoint(const gfx::PointF& new_point,
260 const base::TimeTicks& new_time) {
261 TRACE_EVENT1("ui", "LaserPointerView::AddNewPoint", "new_point",
262 new_point.ToString());
263 TRACE_COUNTER1(
264 "ui", "LaserPointerPredictionError",
265 predicted_laser_points_.GetNumberOfPoints()
266 ? std::round((new_point -
267 predicted_laser_points_.laser_points().front().location)
268 .Length())
269 : 0);
270
249 buffer_damage_rect_.Union(GetBoundingBox()); 271 buffer_damage_rect_.Union(GetBoundingBox());
250 laser_points_.AddPoint(new_point); 272 laser_points_.AddPoint(new_point, new_time);
273
274 // Current time is needed to determine presentation time and the number of
275 // predicted points to add.
276 base::TimeTicks current_time = ui::EventTimeForNow();
277
278 // Create a new set of predicted points based on the last four points added.
279 // We add enough predicted points to fill the time between the new point and
280 // the expected presentation time. Note that estimated presentation time is
281 // based on current time and inefficient rendering of points can result in an
282 // actual presentation time that is later.
283 predicted_laser_points_.Clear();
284
285 // Normalize all coordinates to screen size.
286 gfx::Size screen_size = widget_->GetNativeView()->GetBoundsInScreen().size();
287 gfx::Vector2dF scale(1.0f / screen_size.width(), 1.0f / screen_size.height());
288
289 // TODO(reveman): Determine interval based on history when event time stamps
290 // are accurate. b/36137953
291 const float kPredictionIntervalMs = 5.0f;
292 const float kMaxPointIntervalMs = 10.0f;
293 base::TimeDelta prediction_interval =
294 base::TimeDelta::FromMilliseconds(kPredictionIntervalMs);
295 base::TimeDelta max_point_interval =
296 base::TimeDelta::FromMilliseconds(kMaxPointIntervalMs);
297 base::TimeTicks last_point_time = current_time;
298
299 // Use the last four points for prediction.
300 using PositionArray = std::array<gfx::PointF, 4>;
301 PositionArray position;
302 PositionArray::iterator it = position.begin();
303 for (auto& point : base::Reversed(laser_points_.laser_points())) {
Daniel Erat 2017/03/16 16:50:55 nit: const auto& ?
reveman 2017/03/16 18:00:24 Done.
304 // Stop adding positons if interval between points is too large to provide
Daniel Erat 2017/03/16 16:50:55 nit: positions
reveman 2017/03/16 18:00:24 Done.
305 // an accurate history for prediction.
306 if ((last_point_time - point.time) > max_point_interval)
307 break;
308
309 *it++ = gfx::ScalePoint(point.location, scale.x(), scale.y());
310 last_point_time = point.time;
311
312 // Stop when no more positions are needed.
313 if (it == position.end())
314 break;
315 }
316 // Pad with last point if needed.
317 std::fill(it, position.end(), *(it - 1));
318
319 // Calculate velocity.
Daniel Erat 2017/03/16 16:50:55 nit: i'd drop these "Calculate ..." comments; they
reveman 2017/03/16 18:00:24 Agree. Done.
320 // Note: Currently there's no need to divide by the time delta between
321 // points as we assume a constant delta between points that matches the
322 // prediction point interval.
323 gfx::Vector2dF velocity[3];
324 for (size_t i = 0; i < arraysize(velocity); ++i)
325 velocity[i] = position[i] - position[i + 1];
326
327 // Calculate acceleration.
328 gfx::Vector2dF acceleration[2];
329 for (size_t i = 0; i < arraysize(acceleration); ++i)
330 acceleration[i] = velocity[i] - velocity[i + 1];
331
332 // Calculate jerk.
333 gfx::Vector2dF jerk = acceleration[0] - acceleration[1];
334
335 // Adjust max prediction time based on speed as prediction data is not great
336 // at lower speeds.
337 const float kMaxPredictionScaleSpeed = 1e-5;
338 double speed = velocity[0].LengthSquared();
339 base::TimeTicks max_prediction_time =
340 current_time +
341 std::min(presentation_delay_ * (speed / kMaxPredictionScaleSpeed),
342 presentation_delay_);
343
344 // Add predicted points until we reach the max prediction time.
345 gfx::PointF location = position[0];
346 for (base::TimeTicks time = new_time + prediction_interval;
347 time < max_prediction_time; time += prediction_interval) {
348 // Note: Currently there's no need to multiply by the prediction interval
349 // as the velocity is calculated based on a time delta between points that
350 // is the same as the prediction interval.
351 velocity[0] += acceleration[0];
352 acceleration[0] += jerk;
353 location += velocity[0];
354
355 predicted_laser_points_.AddPoint(
356 gfx::ScalePoint(location, screen_size.width(), screen_size.height()),
357 time);
358
359 // Always stop at three predicted points as a four point history doesn't
360 // provide accurate prediction of more points.
361 if (predicted_laser_points_.GetNumberOfPoints() == 3)
362 break;
363 }
364
365 // Move forward to next presentation time.
366 base::TimeTicks next_presentation_time = current_time + presentation_delay_;
367 laser_points_.MoveForwardToTime(next_presentation_time);
368 predicted_laser_points_.MoveForwardToTime(next_presentation_time);
369
251 buffer_damage_rect_.Union(GetBoundingBox()); 370 buffer_damage_rect_.Union(GetBoundingBox());
252 OnPointsUpdated(); 371 OnPointsUpdated();
253 } 372 }
254 373
255 void LaserPointerView::UpdateTime() { 374 void LaserPointerView::UpdateTime() {
256 buffer_damage_rect_.Union(GetBoundingBox()); 375 buffer_damage_rect_.Union(GetBoundingBox());
257 // Do not add the point but advance the time if the view is in process of 376 // Do not add the point but advance the time if the view is in process of
258 // fading away. 377 // fading away.
259 laser_points_.MoveForwardToTime(base::Time::Now()); 378 base::TimeTicks next_presentation_time =
379 ui::EventTimeForNow() + presentation_delay_;
380 laser_points_.MoveForwardToTime(next_presentation_time);
381 predicted_laser_points_.MoveForwardToTime(next_presentation_time);
260 buffer_damage_rect_.Union(GetBoundingBox()); 382 buffer_damage_rect_.Union(GetBoundingBox());
261 OnPointsUpdated(); 383 OnPointsUpdated();
262 } 384 }
263 385
264 void LaserPointerView::SetNeedsBeginFrame(bool needs_begin_frame) { 386 void LaserPointerView::SetNeedsBeginFrame(bool needs_begin_frame) {
265 frame_sink_support_.SetNeedsBeginFrame(needs_begin_frame); 387 frame_sink_support_.SetNeedsBeginFrame(needs_begin_frame);
266 } 388 }
267 389
268 void LaserPointerView::SubmitCompositorFrame( 390 void LaserPointerView::SubmitCompositorFrame(
269 const cc::LocalSurfaceId& local_surface_id, 391 const cc::LocalSurfaceId& local_surface_id,
(...skipping 25 matching lines...) Expand all
295 gles2->WaitSyncTokenCHROMIUM(resources.front().sync_token.GetConstData()); 417 gles2->WaitSyncTokenCHROMIUM(resources.front().sync_token.GetConstData());
296 418
297 if (!resources.front().lost) 419 if (!resources.front().lost)
298 returned_resources_.push_back(std::move(resource)); 420 returned_resources_.push_back(std::move(resource));
299 } 421 }
300 422
301 gfx::Rect LaserPointerView::GetBoundingBox() { 423 gfx::Rect LaserPointerView::GetBoundingBox() {
302 // Expand the bounding box so that it includes the radius of the points on the 424 // Expand the bounding box so that it includes the radius of the points on the
303 // edges and antialiasing. 425 // edges and antialiasing.
304 gfx::Rect bounding_box = laser_points_.GetBoundingBox(); 426 gfx::Rect bounding_box = laser_points_.GetBoundingBox();
427 bounding_box.Union(predicted_laser_points_.GetBoundingBox());
305 const int kOutsetForAntialiasing = 1; 428 const int kOutsetForAntialiasing = 1;
306 int outset = kPointInitialRadius + kOutsetForAntialiasing; 429 int outset = kPointInitialRadius + kOutsetForAntialiasing;
307 bounding_box.Inset(-outset, -outset); 430 bounding_box.Inset(-outset, -outset);
308 return bounding_box; 431 return bounding_box;
309 } 432 }
310 433
311 void LaserPointerView::OnPointsUpdated() { 434 void LaserPointerView::OnPointsUpdated() {
312 if (pending_update_buffer_) 435 if (pending_update_buffer_)
313 return; 436 return;
314 437
315 pending_update_buffer_ = true; 438 pending_update_buffer_ = true;
316 base::ThreadTaskRunnerHandle::Get()->PostTask( 439 base::ThreadTaskRunnerHandle::Get()->PostTask(
317 FROM_HERE, base::Bind(&LaserPointerView::UpdateBuffer, 440 FROM_HERE, base::Bind(&LaserPointerView::UpdateBuffer,
318 weak_ptr_factory_.GetWeakPtr())); 441 weak_ptr_factory_.GetWeakPtr()));
319 } 442 }
320 443
321 void LaserPointerView::UpdateBuffer() { 444 void LaserPointerView::UpdateBuffer() {
322 TRACE_EVENT2("ui", "LaserPointerView::UpdatedBuffer", "damage", 445 TRACE_EVENT1("ui", "LaserPointerView::UpdatedBuffer", "damage",
323 buffer_damage_rect_.ToString(), "points", 446 buffer_damage_rect_.ToString());
324 laser_points_.GetNumberOfPoints());
325 447
326 DCHECK(pending_update_buffer_); 448 DCHECK(pending_update_buffer_);
327 pending_update_buffer_ = false; 449 pending_update_buffer_ = false;
328 450
329 gfx::Rect screen_bounds = widget_->GetNativeView()->GetBoundsInScreen(); 451 gfx::Rect screen_bounds = widget_->GetNativeView()->GetBoundsInScreen();
330 gfx::Rect update_rect = buffer_damage_rect_; 452 gfx::Rect update_rect = buffer_damage_rect_;
331 buffer_damage_rect_ = gfx::Rect(); 453 buffer_damage_rect_ = gfx::Rect();
332 454
333 // Create and map a single GPU memory buffer. The laser pointer will be 455 // Create and map a single GPU memory buffer. The laser pointer will be
334 // written into this buffer without any buffering. The result is that we 456 // written into this buffer without any buffering. The result is that we
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
372 494
373 cc::PaintFlags flags; 495 cc::PaintFlags flags;
374 flags.setStyle(cc::PaintFlags::kFill_Style); 496 flags.setStyle(cc::PaintFlags::kFill_Style);
375 flags.setAntiAlias(true); 497 flags.setAntiAlias(true);
376 498
377 // Compute the offset of the current widget. 499 // Compute the offset of the current widget.
378 gfx::Vector2d widget_offset( 500 gfx::Vector2d widget_offset(
379 widget_->GetNativeView()->GetBoundsInRootWindow().origin().x(), 501 widget_->GetNativeView()->GetBoundsInRootWindow().origin().x(),
380 widget_->GetNativeView()->GetBoundsInRootWindow().origin().y()); 502 widget_->GetNativeView()->GetBoundsInRootWindow().origin().y());
381 503
382 int num_points = laser_points_.GetNumberOfPoints(); 504 int num_points = laser_points_.GetNumberOfPoints() +
505 predicted_laser_points_.GetNumberOfPoints();
383 if (num_points) { 506 if (num_points) {
384 LaserPointerPoints::LaserPoint previous_point = laser_points_.GetOldest(); 507 LaserPointerPoints::LaserPoint previous_point = laser_points_.GetOldest();
385 previous_point.location -= widget_offset + update_rect.OffsetFromOrigin(); 508 previous_point.location -= widget_offset + update_rect.OffsetFromOrigin();
386 LaserPointerPoints::LaserPoint current_point; 509 LaserPointerPoints::LaserPoint current_point;
387 std::vector<gfx::PointF> previous_segment_points; 510 std::vector<gfx::PointF> previous_segment_points;
388 float previous_radius; 511 float previous_radius;
389 int current_opacity; 512 int current_opacity;
390 513
391 for (int i = 0; i < num_points; ++i) { 514 for (int i = 0; i < num_points; ++i) {
392 current_point = laser_points_.laser_points()[i]; 515 if (i < laser_points_.GetNumberOfPoints()) {
516 current_point = laser_points_.laser_points()[i];
517 } else {
518 current_point =
519 predicted_laser_points_
520 .laser_points()[i - laser_points_.GetNumberOfPoints()];
521 }
393 current_point.location -= widget_offset + update_rect.OffsetFromOrigin(); 522 current_point.location -= widget_offset + update_rect.OffsetFromOrigin();
394 523
395 // Set the radius and opacity based on the distance. 524 // Set the radius and opacity based on the distance.
396 float current_radius = LinearInterpolate( 525 float current_radius = LinearInterpolate(
397 kPointInitialRadius, kPointFinalRadius, current_point.age); 526 kPointInitialRadius, kPointFinalRadius, current_point.age);
398 current_opacity = int{LinearInterpolate( 527 current_opacity = int{LinearInterpolate(
399 kPointInitialOpacity, kPointFinalOpacity, current_point.age)}; 528 kPointInitialOpacity, kPointFinalOpacity, current_point.age)};
400 529
401 // If we draw laser_points_ that are within a stroke width of each other, 530 // If we draw laser_points_ that are within a stroke width of each other,
402 // the result will be very jagged, unless we are on the last point, then 531 // the result will be very jagged, unless we are on the last point, then
403 // we draw regardless. 532 // we draw regardless.
404 float distance_threshold = current_radius * 2.0f; 533 float distance_threshold = current_radius * 2.0f;
405 if (DistanceBetweenPoints(previous_point.location, 534 if (DistanceBetweenPoints(previous_point.location,
406 current_point.location) <= distance_threshold && 535 current_point.location) <= distance_threshold &&
407 i != num_points - 1) { 536 i != num_points - 1) {
408 continue; 537 continue;
409 } 538 }
410 539
411 LaserSegment current_segment( 540 LaserSegment current_segment(
412 previous_segment_points, gfx::PointF(previous_point.location), 541 previous_segment_points, gfx::PointF(previous_point.location),
413 gfx::PointF(current_point.location), previous_radius, current_radius, 542 gfx::PointF(current_point.location), previous_radius, current_radius,
414 i == num_points - 1); 543 i == num_points - 1);
415 544
416 SkPath path = current_segment.path(); 545 SkPath path = current_segment.path();
417 flags.setColor(SkColorSetA(kPointColor, current_opacity)); 546 if (i < laser_points_.GetNumberOfPoints())
547 flags.setColor(SkColorSetA(kPointColor, current_opacity));
548 else
549 flags.setColor(SkColorSetA(kPredictionPointColor, current_opacity));
418 canvas.DrawPath(path, flags); 550 canvas.DrawPath(path, flags);
419 551
420 previous_segment_points = current_segment.path_points(); 552 previous_segment_points = current_segment.path_points();
421 previous_radius = current_radius; 553 previous_radius = current_radius;
422 previous_point = current_point; 554 previous_point = current_point;
423 } 555 }
424 556
425 // Draw the last point as a circle. 557 // Draw the last point as a circle.
426 flags.setColor(SkColorSetA(kPointColor, current_opacity));
427 flags.setStyle(cc::PaintFlags::kFill_Style); 558 flags.setStyle(cc::PaintFlags::kFill_Style);
428 canvas.DrawCircle(current_point.location, kPointInitialRadius, flags); 559 canvas.DrawCircle(current_point.location, kPointInitialRadius, flags);
429 } 560 }
430 561
431 // Copy result to GPU memory buffer. This is effectiely a memcpy and unlike 562 // Copy result to GPU memory buffer. This is effectiely a memcpy and unlike
432 // drawing to the buffer directly this ensures that the buffer is never in a 563 // drawing to the buffer directly this ensures that the buffer is never in a
433 // state that would result in flicker. 564 // state that would result in flicker.
434 { 565 {
435 TRACE_EVENT0("ui", "LaserPointerView::OnPointsUpdated::Copy"); 566 TRACE_EVENT0("ui", "LaserPointerView::OnPointsUpdated::Copy");
436 567
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
584 pending_draw_surface_ = true; 715 pending_draw_surface_ = true;
585 } 716 }
586 717
587 void LaserPointerView::OnDidDrawSurface() { 718 void LaserPointerView::OnDidDrawSurface() {
588 pending_draw_surface_ = false; 719 pending_draw_surface_ = false;
589 if (needs_update_surface_) 720 if (needs_update_surface_)
590 UpdateSurface(); 721 UpdateSurface();
591 } 722 }
592 723
593 } // namespace ash 724 } // namespace ash
OLDNEW
« ash/common/ash_switches.cc ('K') | « ash/laser/laser_pointer_view.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698