Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |