paint_manager.h 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. // Copyright (c) 2010 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 PDF_PAINT_MANAGER_H_
  5. #define PDF_PAINT_MANAGER_H_
  6. #include <vector>
  7. #include "base/memory/raw_ptr.h"
  8. #include "base/memory/weak_ptr.h"
  9. #include "pdf/paint_aggregator.h"
  10. #include "third_party/skia/include/core/SkRefCnt.h"
  11. #include "ui/gfx/geometry/size.h"
  12. class SkImage;
  13. class SkSurface;
  14. namespace gfx {
  15. class Point;
  16. class Rect;
  17. class Vector2d;
  18. class Vector2dF;
  19. } // namespace gfx
  20. namespace chrome_pdf {
  21. // Custom PaintManager for the PDF plugin. This is branched from the Pepper
  22. // version. The difference is that this supports progressive rendering of dirty
  23. // rects, where multiple calls to the rendering engine are needed. It also
  24. // supports having higher-priority rects flushing right away, i.e. the
  25. // scrollbars.
  26. //
  27. // The client's OnPaint
  28. class PaintManager {
  29. public:
  30. class Client {
  31. public:
  32. // Invalidates the entire plugin container, scheduling a repaint.
  33. virtual void InvalidatePluginContainer() = 0;
  34. // Paints the given invalid area of the plugin to the given graphics
  35. // device. Returns true if anything was painted.
  36. //
  37. // You are given the list of rects to paint in `paint_rects`. You can
  38. // combine painting into less rectangles if it's more efficient. When a
  39. // rect is painted, information about that paint should be inserted into
  40. // `ready`. Otherwise if a paint needs more work, add the rect to
  41. // `pending`. If `pending` is not empty, your OnPaint function will get
  42. // called again. Once OnPaint is called and it returns no pending rects,
  43. // all the previously ready rects will be flushed on screen. The exception
  44. // is for ready rects that have `flush_now` set to true. These will be
  45. // flushed right away.
  46. //
  47. // Do not call Flush() on the graphics device, this will be done
  48. // automatically if you return true from this function since the
  49. // PaintManager needs to handle the callback.
  50. //
  51. // Calling Invalidate/Scroll is not allowed while inside an OnPaint
  52. virtual void OnPaint(const std::vector<gfx::Rect>& paint_rects,
  53. std::vector<PaintReadyRect>& ready,
  54. std::vector<gfx::Rect>& pending) = 0;
  55. // Updates the client with the latest snapshot created by `Flush()`.
  56. virtual void UpdateSnapshot(sk_sp<SkImage> snapshot) = 0;
  57. // Updates the client with the latest output scale.
  58. virtual void UpdateScale(float scale) = 0;
  59. // Updates the client with the latest output layer transform.
  60. virtual void UpdateLayerTransform(float scale,
  61. const gfx::Vector2dF& translate) = 0;
  62. protected:
  63. // You shouldn't delete through this interface.
  64. ~Client() = default;
  65. };
  66. // The Client is a non-owning pointer and must remain valid (normally the
  67. // object implementing the Client interface will own the paint manager).
  68. //
  69. // You will need to call SetSize() before this class will do anything.
  70. // Normally you do this from UpdateGeometryOnViewChanged() of your plugin
  71. // instance.
  72. explicit PaintManager(Client* client);
  73. PaintManager(const PaintManager&) = delete;
  74. PaintManager& operator=(const PaintManager&) = delete;
  75. ~PaintManager();
  76. // Returns the size of the graphics context to allocate for a given plugin
  77. // size. We may allocated a slightly larger buffer than required so that we
  78. // don't have to resize the context when scrollbars appear/dissapear due to
  79. // zooming (which can result in flickering).
  80. static gfx::Size GetNewContextSize(const gfx::Size& current_context_size,
  81. const gfx::Size& plugin_size);
  82. // Sets the size of the plugin. If the size is the same as the previous call,
  83. // this will be a NOP. If the size has changed, a new device will be
  84. // allocated to the given size and a paint to that device will be scheduled.
  85. //
  86. // This is intended to be called from ViewChanged with the size of the
  87. // plugin. Since it tracks the old size and only allocates when the size
  88. // changes, you can always call this function without worrying about whether
  89. // the size changed or ViewChanged is called for another reason (like the
  90. // position changed).
  91. void SetSize(const gfx::Size& new_size, float new_device_scale);
  92. // Invalidate the entire plugin.
  93. void Invalidate();
  94. // Invalidate the given rect.
  95. void InvalidateRect(const gfx::Rect& rect);
  96. // The given rect should be scrolled by the given amounts.
  97. void ScrollRect(const gfx::Rect& clip_rect, const gfx::Vector2d& amount);
  98. // Returns the size of the graphics context for the next paint operation.
  99. // This is the pending size if a resize is pending (the plugin has called
  100. // SetSize but we haven't actually painted it yet), or the current size of
  101. // no resize is pending.
  102. gfx::Size GetEffectiveSize() const;
  103. float GetEffectiveDeviceScale() const;
  104. // Set the transform for the graphics layer.
  105. // If `schedule_flush` is true, it ensures a flush will be scheduled for
  106. // this change. If `schedule_flush` is false, then the change will not take
  107. // effect until another change causes a flush.
  108. void SetTransform(float scale,
  109. const gfx::Point& origin,
  110. const gfx::Vector2d& translate,
  111. bool schedule_flush);
  112. // Resets any transform for the graphics layer.
  113. // This does not schedule a flush.
  114. void ClearTransform();
  115. private:
  116. // Makes sure there is a callback that will trigger a paint at a later time.
  117. // This will be either a Flush callback telling us we're allowed to generate
  118. // more data, or, if there's no flush callback pending, a manual call back
  119. // to the message loop via ExecuteOnMainThread.
  120. void EnsureCallbackPending();
  121. // Does the client paint and executes a Flush if necessary.
  122. void DoPaint();
  123. // Executes a Flush.
  124. void Flush();
  125. // Callback for asynchronous completion of Flush.
  126. void OnFlushComplete();
  127. // Callback for manual scheduling of paints when there is no flush callback
  128. // pending.
  129. void OnManualCallbackComplete();
  130. // Non-owning pointer. See the constructor.
  131. const raw_ptr<Client> client_;
  132. // Backing Skia surface.
  133. sk_sp<SkSurface> surface_;
  134. PaintAggregator aggregator_;
  135. // See comment for EnsureCallbackPending for more on how these work.
  136. bool manual_callback_pending_ = false;
  137. bool flush_pending_ = false;
  138. bool flush_requested_ = false;
  139. // When we get a resize, we don't do so right away (see `SetSize()`). The
  140. // `has_pending_resize_` tells us that we need to do a resize for the next
  141. // paint operation. When true, the new size is in `pending_size_`.
  142. bool has_pending_resize_ = false;
  143. gfx::Size pending_size_;
  144. gfx::Size plugin_size_;
  145. float pending_device_scale_ = 1.0f;
  146. float device_scale_ = 1.0f;
  147. // True iff we're in the middle of a paint.
  148. bool in_paint_ = false;
  149. // True if we haven't painted the plugin viewport yet.
  150. bool first_paint_ = true;
  151. // True when the view size just changed and we're waiting for a paint.
  152. bool view_size_changed_waiting_for_paint_ = false;
  153. base::WeakPtrFactory<PaintManager> weak_factory_{this};
  154. };
  155. } // namespace chrome_pdf
  156. #endif // PDF_PAINT_MANAGER_H_