window_resize_helper_mac.h 3.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. // Copyright 2015 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef UI_ACCELERATED_WIDGET_MAC_WINDOW_RESIZE_HELPER_MAC_H_
  5. #define UI_ACCELERATED_WIDGET_MAC_WINDOW_RESIZE_HELPER_MAC_H_
  6. #include "base/lazy_instance.h"
  7. #include "base/memory/ref_counted.h"
  8. #include "ui/accelerated_widget_mac/accelerated_widget_mac_export.h"
  9. namespace base {
  10. class SingleThreadTaskRunner;
  11. class TimeDelta;
  12. class WaitableEvent;
  13. }
  14. namespace ui {
  15. // WindowResizeHelperMac is used to make resize appear smooth. That is to
  16. // say, make sure that the window size and the size of the contents being drawn
  17. // in that window are resized in lock-step. This is accomplished by waiting
  18. // inside AppKit drawing routines on the UI thread for the compositor to produce
  19. // a frame of same size as the NSView that hosts an AcceleratedWidgetMac. When a
  20. // resize occurs, the view controller can wait for a frame of the correct size
  21. // by calling WindowResizeHelperMac::WaitForSingleTaskToRun() until a timeout
  22. // occurs, or the corresponding AcceleratedWidgetMac has a renderer frame of the
  23. // same size as its NSView.
  24. //
  25. // By posting tasks to the custom task_runner(), other threads indicate tasks
  26. // that are required to pick up a new frame. In the ordinary run of things these
  27. // would be posted to the |target_task_runner|; the UI thread given as an
  28. // argument to Init(). Posting instead to task_runner() will cause the tasks to
  29. // be posted to the UI thread (as usual), and will also enqueue them into a
  30. // queue which will be read and run in WaitForSingleTaskToRun(), potentially
  31. // before the task posted to the UI thread is run. Some care is taken (see
  32. // WrappedTask) to make sure that the messages are only executed once.
  33. //
  34. // This is further complicated because, in order for a frame to appear, it is
  35. // also necessary to run tasks posted by the ui::Compositor. To accomplish this,
  36. // the task_runner() that WindowResizeHelperMac provides can be used to
  37. // construct a ui::Compositor. When the Compositor posts tasks to it, they are
  38. // enqueued in the aforementioned queue, which may be pumped by
  39. // WindowResizeHelperMac::WaitForSingleTaskToRun().
  40. class ACCELERATED_WIDGET_MAC_EXPORT WindowResizeHelperMac {
  41. public:
  42. static WindowResizeHelperMac* Get();
  43. WindowResizeHelperMac(const WindowResizeHelperMac&) = delete;
  44. WindowResizeHelperMac& operator=(const WindowResizeHelperMac&) = delete;
  45. // Initializes the pumpable task_runner(), providing it with the task runner
  46. // for UI thread tasks. task_runner() will be null before Init() is called,
  47. // and WaitForSingleTaskToRun() will immediately return false.
  48. void Init(
  49. const scoped_refptr<base::SingleThreadTaskRunner>& target_task_runner);
  50. // Because this class is global, many tests may want to do this setup
  51. // repeatedly, so need some way to uninitialize as well.
  52. void ShutdownForTests();
  53. scoped_refptr<base::SingleThreadTaskRunner> task_runner() const;
  54. // UI THREAD ONLY -----------------------------------------------------------
  55. // Waits at most |max_delay| for a task to run. Returns true if a task ran,
  56. // false if no task ran.
  57. bool WaitForSingleTaskToRun(const base::TimeDelta& max_delay);
  58. private:
  59. friend struct base::LazyInstanceTraitsBase<WindowResizeHelperMac>;
  60. WindowResizeHelperMac();
  61. ~WindowResizeHelperMac();
  62. // This helper is needed to create a ScopedAllowWait inside the scope of a
  63. // class where it is allowed.
  64. static void EventTimedWait(base::WaitableEvent* event, base::TimeDelta delay);
  65. // The task runner to which the helper will post tasks. This also maintains
  66. // the task queue and does the actual work for WaitForSingleTaskToRun.
  67. scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
  68. };
  69. } // namespace ui
  70. #endif // UI_ACCELERATED_WIDGET_MAC_WINDOW_RESIZE_HELPER_MAC_H_