| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2011 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 | |
| 5 #ifndef PPAPI_CPP_PAINT_MANAGER_H_ | |
| 6 #define PPAPI_CPP_PAINT_MANAGER_H_ | |
| 7 | |
| 8 #include <vector> | |
| 9 | |
| 10 #include "ppapi/cpp/completion_callback.h" | |
| 11 #include "ppapi/cpp/graphics_2d.h" | |
| 12 #include "ppapi/cpp/paint_aggregator.h" | |
| 13 | |
| 14 /// @file | |
| 15 /// This file defines the API to convert the "plugin push" model of painting | |
| 16 /// in PPAPI to a paint request at a later time. | |
| 17 | |
| 18 namespace pp { | |
| 19 | |
| 20 class Graphics2D; | |
| 21 class Instance; | |
| 22 class Point; | |
| 23 class Rect; | |
| 24 | |
| 25 /// This class converts the "instance push" model of painting in PPAPI to a | |
| 26 /// paint request at a later time. Usage is that you call Invalidate and | |
| 27 /// Scroll, and implement the Client interface. Your OnPaint handler will | |
| 28 /// then get called with coalesced paint events. | |
| 29 /// | |
| 30 /// This class is basically a <code>PaintAggregator</code> that groups updates, | |
| 31 /// plus management of callbacks for scheduling paints. | |
| 32 /// | |
| 33 /// <strong>Example:</strong> | |
| 34 /// | |
| 35 /// <code> | |
| 36 /// | |
| 37 /// class MyClass : public pp::Instance, public PaintManager::Client { | |
| 38 /// public: | |
| 39 /// MyClass() { | |
| 40 /// paint_manager_.Initialize(this, this, false); | |
| 41 /// } | |
| 42 /// | |
| 43 /// void ViewChanged(const pp::Rect& position, const pp::Rect& clip) { | |
| 44 /// paint_manager_.SetSize(position.size()); | |
| 45 /// } | |
| 46 /// | |
| 47 /// void DoSomething() { | |
| 48 /// // This function does something like respond to an event that causes | |
| 49 /// // the screen to need updating. | |
| 50 /// paint_manager_.InvalidateRect(some_rect); | |
| 51 /// } | |
| 52 /// | |
| 53 /// // Implementation of PaintManager::Client | |
| 54 /// virtual bool OnPaint(pp::Graphics2D& device, | |
| 55 /// const pp::PaintUpdate& update) { | |
| 56 /// // If our app needed scrolling, we would apply that first here. | |
| 57 /// | |
| 58 /// // Then we would either repaint the area returned by GetPaintBounds or | |
| 59 /// // iterate through all the paint_rects. | |
| 60 /// | |
| 61 /// // The caller will call Flush() for us, so don't do that here. | |
| 62 /// return true; | |
| 63 /// } | |
| 64 /// | |
| 65 /// private: | |
| 66 /// pp::PaintManager paint_manager_; | |
| 67 /// }; | |
| 68 /// </code> | |
| 69 class PaintManager { | |
| 70 public: | |
| 71 class Client { | |
| 72 public: | |
| 73 /// OnPaint() paints the given invalid area of the instance to the given | |
| 74 /// graphics device. Returns true if anything was painted. | |
| 75 /// | |
| 76 /// You are given the list of rects to paint in <code>paint_rects</code>, | |
| 77 /// and the union of all of these rects in <code>paint_bounds</code>. You | |
| 78 /// only have to paint the area inside each of the | |
| 79 /// <code>paint_rects</code>, but can paint more if you want (some apps may | |
| 80 /// just want to paint the union). | |
| 81 /// | |
| 82 /// Do not call Flush() on the graphics device, this will be done | |
| 83 /// automatically if you return true from this function since the | |
| 84 /// <code>PaintManager</code> needs to handle the callback. | |
| 85 /// | |
| 86 /// It is legal for you to cause invalidates inside of Paint which will | |
| 87 /// then get executed as soon as the Flush for this update has completed. | |
| 88 /// However, this is not very nice to the host system since it will spin the | |
| 89 /// CPU, possibly updating much faster than necessary. It is best to have a | |
| 90 /// 1/60 second timer to do an invalidate instead. This will limit your | |
| 91 /// animation to the slower of 60Hz or "however fast Flush can complete." | |
| 92 /// | |
| 93 /// @param[in] graphics A <code>Graphics2D</code> to be painted. | |
| 94 /// @param[in] paint_rects A list of rects to paint. | |
| 95 /// @param[in] paint_bounds A union of the rects to paint. | |
| 96 /// | |
| 97 /// @return true if successful, otherwise false. | |
| 98 virtual bool OnPaint(Graphics2D& graphics, | |
| 99 const std::vector<Rect>& paint_rects, | |
| 100 const Rect& paint_bounds) = 0; | |
| 101 | |
| 102 protected: | |
| 103 // You shouldn't be doing deleting through this interface. | |
| 104 virtual ~Client() {} | |
| 105 }; | |
| 106 | |
| 107 /// Default constructor for creating an is_null() <code>PaintManager</code> | |
| 108 /// object. If you use this version of the constructor, you must call | |
| 109 /// Initialize() below. | |
| 110 PaintManager(); | |
| 111 | |
| 112 /// A constructor to create a new <code>PaintManager</code> with an instance | |
| 113 /// and client. | |
| 114 /// | |
| 115 /// <strong>Note:</strong> You will need to call SetSize() before this class | |
| 116 /// will do anything. Normally you do this from the <code>ViewChanged</code> | |
| 117 /// method of your instance. | |
| 118 /// | |
| 119 /// @param instance The instance using this paint manager to do its | |
| 120 /// painting. Painting will automatically go to this instance and you don't | |
| 121 /// have to manually bind any device context (this is all handled by the | |
| 122 /// paint manager). | |
| 123 /// | |
| 124 /// @param client A non-owning pointer and must remain valid (normally the | |
| 125 /// object implementing the Client interface will own the paint manager). | |
| 126 /// | |
| 127 /// @param is_always_opaque A flag passed to the device contexts that this | |
| 128 /// class creates. Set this to true if your instance always draws an opaque | |
| 129 /// image to the device. This is used as a hint to the browser that it does | |
| 130 /// not need to do alpha blending, which speeds up painting. If you generate | |
| 131 /// non-opqaue pixels or aren't sure, set this to false for more general | |
| 132 /// blending. | |
| 133 /// | |
| 134 /// If you set is_always_opaque, your alpha channel should always be set to | |
| 135 /// 0xFF or there may be painting artifacts. Being opaque will allow the | |
| 136 /// browser to do a memcpy rather than a blend to paint the plugin, and this | |
| 137 /// means your alpha values will get set on the page backing store. If these | |
| 138 /// values are incorrect, it could mess up future blending. If you aren't | |
| 139 /// sure, it is always correct to specify that it it not opaque. | |
| 140 PaintManager(Instance* instance, Client* client, bool is_always_opaque); | |
| 141 | |
| 142 /// Destructor. | |
| 143 ~PaintManager(); | |
| 144 | |
| 145 /// Initialize() must be called if you are using the 0-arg constructor. | |
| 146 /// | |
| 147 /// @param instance The instance using this paint manager to do its | |
| 148 /// painting. Painting will automatically go to this instance and you don't | |
| 149 /// have to manually bind any device context (this is all handled by the | |
| 150 /// paint manager). | |
| 151 /// @param client A non-owning pointer and must remain valid (normally the | |
| 152 /// object implementing the Client interface will own the paint manager). | |
| 153 /// @param is_always_opaque A flag passed to the device contexts that this | |
| 154 /// class creates. Set this to true if your instance always draws an opaque | |
| 155 /// image to the device. This is used as a hint to the browser that it does | |
| 156 /// not need to do alpha blending, which speeds up painting. If you generate | |
| 157 /// non-opqaue pixels or aren't sure, set this to false for more general | |
| 158 /// blending. | |
| 159 /// | |
| 160 /// If you set <code>is_always_opaque</code>, your alpha channel should | |
| 161 /// always be set to <code>0xFF</code> or there may be painting artifacts. | |
| 162 /// Being opaque will allow the browser to do a memcpy rather than a blend | |
| 163 /// to paint the plugin, and this means your alpha values will get set on the | |
| 164 /// page backing store. If these values are incorrect, it could mess up | |
| 165 /// future blending. If you aren't sure, it is always correct to specify that | |
| 166 /// it it not opaque. | |
| 167 void Initialize(Instance* instance, Client* client, bool is_always_opaque); | |
| 168 | |
| 169 /// Setter function setting the max ratio of paint rect area to scroll rect | |
| 170 /// area that we will tolerate before downgrading the scroll into a repaint. | |
| 171 /// | |
| 172 /// If the combined area of paint rects contained within the scroll | |
| 173 /// rect grows too large, then we might as well just treat | |
| 174 /// the scroll rect as a paint rect. | |
| 175 /// | |
| 176 /// @param[in] area The max ratio of paint rect area to scroll rect area that | |
| 177 /// we will tolerate before downgrading the scroll into a repaint. | |
| 178 void set_max_redundant_paint_to_scroll_area(float area) { | |
| 179 aggregator_.set_max_redundant_paint_to_scroll_area(area); | |
| 180 } | |
| 181 | |
| 182 /// Setter function for setting the maximum number of paint rects. If we | |
| 183 /// exceed this limit, then we'll start combining paint rects (refer to | |
| 184 /// CombinePaintRects() for further information). This limiting can be | |
| 185 /// important since there is typically some overhead in deciding what to | |
| 186 /// paint. If your module is fast at doing these computations, raise this | |
| 187 /// threshold, if your module is slow, lower it (probably requires some | |
| 188 /// tuning to find the right value). | |
| 189 /// | |
| 190 /// @param[in] max_rects The maximum number of paint rects. | |
| 191 void set_max_paint_rects(size_t max_rects) { | |
| 192 aggregator_.set_max_paint_rects(max_rects); | |
| 193 } | |
| 194 | |
| 195 /// SetSize() sets the size of the instance. If the size is the same as the | |
| 196 /// previous call, this will be a NOP. If the size has changed, a new device | |
| 197 /// will be allocated to the given size and a paint to that device will be | |
| 198 /// scheduled. | |
| 199 /// | |
| 200 /// This function is intended to be called from <code>ViewChanged</code> with | |
| 201 /// the size of the instance. Since it tracks the old size and only allocates | |
| 202 /// when the size changes, you can always call this function without worrying | |
| 203 /// about whether the size changed or ViewChanged() is called for another | |
| 204 /// reason (like the position changed). | |
| 205 /// | |
| 206 /// @param new_size The new size for the instance. | |
| 207 void SetSize(const Size& new_size); | |
| 208 | |
| 209 /// This function provides access to the underlying device in case you need | |
| 210 /// it. If you have done a SetSize(), note that the graphics context won't be | |
| 211 /// updated until right before the next call to OnPaint(). | |
| 212 /// | |
| 213 /// <strong>Note:</strong> If you call Flush on this device the paint manager | |
| 214 /// will get very confused, don't do this! | |
| 215 const Graphics2D& graphics() const { return graphics_; } | |
| 216 | |
| 217 /// This function provides access to the underlying device in case you need | |
| 218 /// it. If you have done a SetSize(), note that the graphics context won't be | |
| 219 /// updated until right before the next call to OnPaint(). | |
| 220 /// | |
| 221 /// <strong>Note:</strong> If you call Flush on this device the paint manager | |
| 222 /// will get very confused, don't do this! | |
| 223 Graphics2D& graphics() { return graphics_; } | |
| 224 | |
| 225 /// Invalidate() invalidate the entire instance. | |
| 226 void Invalidate(); | |
| 227 | |
| 228 /// InvalidateRect() Invalidate the provided rect. | |
| 229 /// | |
| 230 /// @param[in] rect The <code>Rect</code> to be invalidated. | |
| 231 void InvalidateRect(const Rect& rect); | |
| 232 | |
| 233 /// ScrollRect() scrolls the provided <code>clip_rect</code> by the | |
| 234 /// <code>amount</code> argument. | |
| 235 /// | |
| 236 /// @param clip_rect The clip rectangle to scroll. | |
| 237 /// @param amount The amount to scroll <code>clip_rect</code>. | |
| 238 void ScrollRect(const Rect& clip_rect, const Point& amount); | |
| 239 | |
| 240 /// GetEffectiveSize() returns the size of the graphics context for the | |
| 241 /// next paint operation. This is the pending size if a resize is pending | |
| 242 /// (the instance has called SetSize() but we haven't actually painted it | |
| 243 /// yet), or the current size of no resize is pending. | |
| 244 /// | |
| 245 /// @return The effective size. | |
| 246 Size GetEffectiveSize() const; | |
| 247 | |
| 248 private: | |
| 249 // Disallow copy and assign (these are unimplemented). | |
| 250 PaintManager(const PaintManager&); | |
| 251 PaintManager& operator=(const PaintManager&); | |
| 252 | |
| 253 // Makes sure there is a callback that will trigger a paint at a later time. | |
| 254 // This will be either a Flush callback telling us we're allowed to generate | |
| 255 // more data, or, if there's no flush callback pending, a manual call back | |
| 256 // to the message loop via ExecuteOnMainThread. | |
| 257 void EnsureCallbackPending(); | |
| 258 | |
| 259 // Does the client paint and executes a Flush if necessary. | |
| 260 void DoPaint(); | |
| 261 | |
| 262 // Callback for asynchronous completion of Flush. | |
| 263 void OnFlushComplete(int32_t); | |
| 264 | |
| 265 // Callback for manual scheduling of paints when there is no flush callback | |
| 266 // pending. | |
| 267 void OnManualCallbackComplete(int32_t); | |
| 268 | |
| 269 Instance* instance_; | |
| 270 | |
| 271 // Non-owning pointer. See the constructor. | |
| 272 Client* client_; | |
| 273 | |
| 274 bool is_always_opaque_; | |
| 275 | |
| 276 CompletionCallbackFactory<PaintManager> callback_factory_; | |
| 277 | |
| 278 // This graphics device will be is_null() if no graphics has been manually | |
| 279 // set yet. | |
| 280 Graphics2D graphics_; | |
| 281 | |
| 282 PaintAggregator aggregator_; | |
| 283 | |
| 284 // See comment for EnsureCallbackPending for more on how these work. | |
| 285 bool manual_callback_pending_; | |
| 286 bool flush_pending_; | |
| 287 | |
| 288 // When we get a resize, we don't bind right away (see SetSize). The | |
| 289 // has_pending_resize_ tells us that we need to do a resize for the next | |
| 290 // paint operation. When true, the new size is in pending_size_. | |
| 291 bool has_pending_resize_; | |
| 292 Size pending_size_; | |
| 293 }; | |
| 294 | |
| 295 } // namespace pp | |
| 296 | |
| 297 #endif // PPAPI_CPP_PAINT_MANAGER_H_ | |
| OLD | NEW |