| // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef PPAPI_CPP_PAINT_MANAGER_H_ |
| #define PPAPI_CPP_PAINT_MANAGER_H_ |
| |
| #include <vector> |
| |
| #include "ppapi/cpp/completion_callback.h" |
| #include "ppapi/cpp/graphics_2d.h" |
| #include "ppapi/cpp/paint_aggregator.h" |
| |
| namespace pp { |
| |
| class Graphics2D; |
| class Instance; |
| class Point; |
| class Rect; |
| |
| // This class converts the "plugin push" model of painting in PPAPI to a paint |
| // request at a later time. Usage is that you call Invalidate and Scroll, and |
| // implement the Client interface. Your OnPaint handler will then get called |
| // with coalesced paint events. |
| // |
| // This class is basically a PaintAggregator that groups updates, plus |
| // management of callbacks for scheduling paints. |
| // |
| // Typical usage: |
| // |
| // class MyClass : public pp::Instance, public PaintManager::Client { |
| // public: |
| // MyClass() { |
| // paint_manager_.Initialize(this, this, false); |
| // } |
| // |
| // void ViewChanged(const pp::Rect& position, const pp::Rect& clip) { |
| // paint_manager_.SetSize(position.size()); |
| // } |
| // |
| // void DoSomething() { |
| // // This function does something like respond to an event that causes |
| // // the screen to need updating. |
| // paint_manager_.InvalidateRect(some_rect); |
| // } |
| // |
| // // Implementation of PaintManager::Client |
| // virtual bool OnPaint(pp::Graphics2D& device, |
| // const pp::PaintUpdate& update) { |
| // // If our app needed scrolling, we would apply that first here. |
| // |
| // // Then we would either repaint the area returned by GetPaintBounds or |
| // // iterate through all the paint_rects. |
| // |
| // // The caller will call Flush() for us, so don't do that here. |
| // return true; |
| // } |
| // |
| // private: |
| // pp::PaintManager paint_manager_; |
| // }; |
| class PaintManager { |
| public: |
| class Client { |
| public: |
| // Paints the given invalid area of the plugin to the given graphics |
| // device. Returns true if anything was painted. |
| // |
| // You are given the list of rects to paint in |paint_rects|, and the |
| // union of all of these rects in |paint_bounds|. You only have to paint |
| // the area inside each of the |paint_rects|, but can paint more if you |
| // want (some apps may just want to paint the union). |
| // |
| // Do not call Flush() on the graphics device, this will be done |
| // automatically if you return true from this function since the |
| // PaintManager needs to handle the callback. |
| // |
| // It is legal for you to cause invalidates inside of Paint which will |
| // then get executed as soon as the Flush for this update has completed. |
| // However, this is not very nice to the host system since it will spin the |
| // CPU, possibly updating much faster than necessary. It is best to have a |
| // 1/60 second timer to do an invalidate instead. This will limit your |
| // animation to the slower of 60Hz or "however fast Flush can complete." |
| virtual bool OnPaint(Graphics2D& graphics, |
| const std::vector<Rect>& paint_rects, |
| const Rect& paint_bounds) = 0; |
| |
| protected: |
| // You shouldn't be doing deleting through this interface. |
| virtual ~Client() {} |
| }; |
| |
| // If you use this version of the constructor, you must call Initialize() |
| // below. |
| PaintManager(); |
| |
| // The instance is the plugin instance using this paint manager to do its |
| // painting. Painting will automatically go to this instance and you don't |
| // have to manually bind any device context (this is all handled by the |
| // paint manager). |
| // |
| // The Client is a non-owning pointer and must remain valid (normally the |
| // object implementing the Client interface will own the paint manager). |
| // |
| // The is_always_opaque flag will be passed to the device contexts that this |
| // class creates. Set this to true if your plugin always draws an opaque |
| // image to the device. This is used as a hint to the browser that it does |
| // not need to do alpha blending, which speeds up painting. If you generate |
| // non-opqaue pixels or aren't sure, set this to false for more general |
| // blending. |
| // |
| // If you set is_always_opaque, your alpha channel should always be set to |
| // 0xFF or there may be painting artifacts. Being opaque will allow the |
| // browser to do a memcpy rather than a blend to paint the plugin, and this |
| // means your alpha values will get set on the page backing store. If these |
| // values are incorrect, it could mess up future blending. If you aren't |
| // sure, it is always correct to specify that it it not opaque. |
| // |
| // You will need to call SetSize before this class will do anything. Normally |
| // you do this from the ViewChanged method of your plugin instance. |
| PaintManager(Instance* instance, Client* client, bool is_always_opaque); |
| |
| ~PaintManager(); |
| |
| // You must call this function before using if you use the 0-arg constructor. |
| // See the constructor for what these arguments mean. |
| void Initialize(Instance* instance, Client* client, bool is_always_opaque); |
| |
| // Setters for the configuration settings in the paint aggregator. |
| // See paint_aggregator.h for what these mean. |
| void set_max_redundant_paint_to_scroll_area(float area) { |
| aggregator_.set_max_redundant_paint_to_scroll_area(area); |
| } |
| void set_max_paint_rects(size_t max_rects) { |
| aggregator_.set_max_paint_rects(max_rects); |
| } |
| |
| // Sets the size of the plugin. If the size is the same as the previous call, |
| // this will be a NOP. If the size has changed, a new device will be |
| // allocated to the given size and a paint to that device will be scheduled. |
| // |
| // This is intended to be called from ViewChanged with the size of the |
| // plugin. Since it tracks the old size and only allocates when the size |
| // changes, you can always call this function without worrying about whether |
| // the size changed or ViewChanged is called for another reason (like the |
| // position changed). |
| void SetSize(const Size& new_size); |
| |
| // Provides access to the underlying device in case you need it. Note: if |
| // you call Flush on this device the paint manager will get very confused, |
| // don't do this! |
| const Graphics2D& graphics() const { return graphics_; } |
| Graphics2D& graphics() { return graphics_; } |
| |
| // Invalidate the entire plugin. |
| void Invalidate(); |
| |
| // Invalidate the given rect. |
| void InvalidateRect(const Rect& rect); |
| |
| // The given rect should be scrolled by the given amounts. |
| void ScrollRect(const Rect& clip_rect, const Point& amount); |
| |
| private: |
| // Disallow copy and assign (these are unimplemented). |
| PaintManager(const PaintManager&); |
| PaintManager& operator=(const PaintManager&); |
| |
| // Makes sure there is a callback that will trigger a paint at a later time. |
| // This will be either a Flush callback telling us we're allowed to generate |
| // more data, or, if there's no flush callback pending, a manual call back |
| // to the message loop via ExecuteOnMainThread. |
| void EnsureCallbackPending(); |
| |
| // Does the client paint and executes a Flush if necessary. |
| void DoPaint(); |
| |
| // Callback for asynchronous completion of Flush. |
| void OnFlushComplete(int32_t); |
| |
| // Callback for manual scheduling of paints when there is no flush callback |
| // pending. |
| void OnManualCallbackComplete(int32_t); |
| |
| Instance* instance_; |
| |
| // Non-owning pointer. See the constructor. |
| Client* client_; |
| |
| bool is_always_opaque_; |
| |
| CompletionCallbackFactory<PaintManager> callback_factory_; |
| |
| // This graphics device will be is_null() if no graphics has been manually |
| // set yet. |
| Graphics2D graphics_; |
| |
| PaintAggregator aggregator_; |
| |
| // See comment for EnsureCallbackPending for more on how these work. |
| bool manual_callback_pending_; |
| bool flush_pending_; |
| }; |
| |
| } // namespace pp |
| |
| #endif // PPAPI_CPP_PAINT_MANAGER_H_ |