OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2012 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. | |
dmichael (off chromium)
2013/04/26 19:30:26
Thanks for catching this. This feels like it shoul
| |
4 | |
5 #ifndef WEBKIT_PLUGINS_PPAPI_PPB_GRAPHICS_2D_IMPL_H_ | |
6 #define WEBKIT_PLUGINS_PPAPI_PPB_GRAPHICS_2D_IMPL_H_ | |
7 | |
8 #include <vector> | |
9 | |
10 #include "base/basictypes.h" | |
11 #include "base/memory/weak_ptr.h" | |
12 #include "ppapi/c/pp_completion_callback.h" | |
13 #include "ppapi/c/ppb_graphics_2d.h" | |
14 #include "ppapi/shared_impl/resource.h" | |
15 #include "ppapi/shared_impl/tracked_callback.h" | |
16 #include "ppapi/thunk/ppb_graphics_2d_api.h" | |
17 #include "third_party/WebKit/Source/Platform/chromium/public/WebCanvas.h" | |
18 #include "webkit/plugins/webkit_plugins_export.h" | |
19 | |
20 namespace gfx { | |
21 class Point; | |
22 class Rect; | |
23 } | |
24 | |
25 namespace content { | |
26 class PepperGraphics2DHost; | |
27 } | |
28 | |
29 namespace webkit { | |
30 namespace ppapi { | |
31 | |
32 class PPB_ImageData_Impl; | |
33 class PluginInstance; | |
34 | |
35 class WEBKIT_PLUGINS_EXPORT PPB_Graphics2D_Impl : | |
36 public ::ppapi::Resource, | |
37 public ::ppapi::thunk::PPB_Graphics2D_API { | |
38 public: | |
39 virtual ~PPB_Graphics2D_Impl(); | |
40 | |
41 static PP_Resource Create(PP_Instance instance, | |
42 const PP_Size& size, | |
43 PP_Bool is_always_opaque); | |
44 | |
45 bool is_always_opaque() const { return is_always_opaque_; } | |
46 | |
47 // Resource overrides. | |
48 virtual ::ppapi::thunk::PPB_Graphics2D_API* AsPPB_Graphics2D_API(); | |
49 virtual void LastPluginRefWasDeleted() OVERRIDE; | |
50 | |
51 // PPB_Graphics2D functions. | |
52 virtual PP_Bool Describe(PP_Size* size, PP_Bool* is_always_opaque) OVERRIDE; | |
53 virtual void PaintImageData(PP_Resource image_data, | |
54 const PP_Point* top_left, | |
55 const PP_Rect* src_rect) OVERRIDE; | |
56 virtual void Scroll(const PP_Rect* clip_rect, | |
57 const PP_Point* amount) OVERRIDE; | |
58 virtual void ReplaceContents(PP_Resource image_data) OVERRIDE; | |
59 virtual bool SetScale(float scale) OVERRIDE; | |
60 virtual float GetScale() OVERRIDE; | |
61 virtual int32_t Flush( | |
62 scoped_refptr< ::ppapi::TrackedCallback> callback, | |
63 PP_Resource* old_image_data) OVERRIDE; | |
64 | |
65 bool ReadImageData(PP_Resource image, const PP_Point* top_left); | |
66 | |
67 // Assciates this device with the given plugin instance. You can pass NULL to | |
68 // clear the existing device. Returns true on success. In this case, a | |
69 // repaint of the page will also be scheduled. Failure means that the device | |
70 // is already bound to a different instance, and nothing will happen. | |
71 bool BindToInstance(PluginInstance* new_instance); | |
72 | |
73 // Paints the current backing store to the web page. | |
74 void Paint(WebKit::WebCanvas* canvas, | |
75 const gfx::Rect& plugin_rect, | |
76 const gfx::Rect& paint_rect); | |
77 | |
78 // Notifications about the view's progress painting. See PluginInstance. | |
79 // These messages are used to send Flush callbacks to the plugin. | |
80 void ViewWillInitiatePaint(); | |
81 void ViewInitiatedPaint(); | |
82 void ViewFlushedPaint(); | |
83 | |
84 PPB_ImageData_Impl* image_data() { return image_data_.get(); } | |
85 PluginInstance* bound_instance() const { return bound_instance_; } | |
86 | |
87 // Scale |op_rect| to logical pixels, taking care to include partially- | |
88 // covered logical pixels (aka DIPs). Also scale optional |delta| to logical | |
89 // pixels as well for scrolling cases. Returns false for scrolling cases where | |
90 // scaling either |op_rect| or |delta| would require scrolling to fall back to | |
91 // invalidation due to rounding errors, true otherwise. | |
92 static bool ConvertToLogicalPixels(float scale, | |
93 gfx::Rect* op_rect, | |
94 gfx::Point* delta); | |
95 | |
96 private: | |
97 explicit PPB_Graphics2D_Impl(PP_Instance instance); | |
98 | |
99 bool Init(int width, int height, bool is_always_opaque); | |
100 | |
101 // Tracks a call to flush that requires a callback. | |
102 class FlushCallbackData { | |
103 public: | |
104 FlushCallbackData() { | |
105 Clear(); | |
106 } | |
107 | |
108 explicit FlushCallbackData( | |
109 scoped_refptr< ::ppapi::TrackedCallback> callback) { | |
110 Set(callback); | |
111 } | |
112 | |
113 bool is_null() const { | |
114 return !::ppapi::TrackedCallback::IsPending(callback_); | |
115 } | |
116 | |
117 void Set(scoped_refptr< ::ppapi::TrackedCallback> callback) { | |
118 callback_ = callback; | |
119 } | |
120 | |
121 void Clear() { | |
122 callback_ = NULL; | |
123 } | |
124 | |
125 void Execute(int32_t result) { | |
126 callback_->Run(result); | |
127 } | |
128 | |
129 void PostAbort() { | |
130 if (!is_null()) { | |
131 callback_->PostAbort(); | |
132 Clear(); | |
133 } | |
134 } | |
135 | |
136 private: | |
137 scoped_refptr< ::ppapi::TrackedCallback> callback_; | |
138 }; | |
139 | |
140 // Called internally to execute the different queued commands. The | |
141 // parameters to these functions will have already been validated. The last | |
142 // rect argument will be filled by each function with the area affected by | |
143 // the update that requires invalidation. If there were no pixels changed, | |
144 // this rect can be untouched. | |
145 void ExecutePaintImageData(PPB_ImageData_Impl* image, | |
146 int x, int y, | |
147 const gfx::Rect& src_rect, | |
148 gfx::Rect* invalidated_rect); | |
149 void ExecuteScroll(const gfx::Rect& clip, int dx, int dy, | |
150 gfx::Rect* invalidated_rect); | |
151 void ExecuteReplaceContents(PPB_ImageData_Impl* image, | |
152 gfx::Rect* invalidated_rect, | |
153 PP_Resource* old_image_data); | |
154 | |
155 // Schedules the offscreen callback to be fired at a future time. This | |
156 // will add the given item to the offscreen_flush_callbacks_ vector. | |
157 void ScheduleOffscreenCallback(const FlushCallbackData& callback); | |
158 | |
159 // Function scheduled to execute by ScheduleOffscreenCallback that actually | |
160 // issues the offscreen callbacks. | |
161 void ExecuteOffscreenCallback(FlushCallbackData data); | |
162 | |
163 // Returns true if there is any type of flush callback pending. | |
164 bool HasPendingFlush() const; | |
165 | |
166 scoped_refptr<PPB_ImageData_Impl> image_data_; | |
167 | |
168 // Non-owning pointer to the plugin instance this context is currently bound | |
169 // to, if any. If the context is currently unbound, this will be NULL. | |
170 PluginInstance* bound_instance_; | |
171 | |
172 // Keeps track of all drawing commands queued before a Flush call. | |
173 struct QueuedOperation; | |
174 typedef std::vector<QueuedOperation> OperationQueue; | |
175 OperationQueue queued_operations_; | |
176 | |
177 // The plugin can give us one "Flush" at a time. This flush will either be in | |
178 // the "unpainted" state (in which case unpainted_flush_callback_ will be | |
179 // non-NULL) or painted, in which case painted_flush_callback_ will be | |
180 // non-NULL). There can also be an offscreen callback which is handled | |
181 // separately (see offscreen_callback_pending_). Only one of these three | |
182 // things may be set at a time to enforce the "only one pending flush at a | |
183 // time" constraint. | |
184 // | |
185 // "Unpainted" ones are flush requests which have never been painted. These | |
186 // could have been done while the RenderView was already waiting for an ACK | |
187 // from a previous paint, so won't generate a new one yet. | |
188 // | |
189 // "Painted" ones are those flushes that have been painted by RenderView, but | |
190 // for which the ACK from the browser has not yet been received. | |
191 // | |
192 // When we get updates from a plugin with a callback, it is first added to | |
193 // the unpainted callbacks. When the renderer has initiated the paint, we move | |
194 // it to the painted callback. When the renderer receives a flush, we execute | |
195 // and clear the painted callback. This helps avoid the callback being called | |
196 // prematurely in response to flush notifications for a previous update. | |
197 FlushCallbackData unpainted_flush_callback_; | |
198 FlushCallbackData painted_flush_callback_; | |
199 | |
200 // When doing offscreen flushes, we issue a task that issues the callback | |
201 // later. This is set when one of those tasks is pending so that we can | |
202 // enforce the "only one pending flush at a time" constraint in the API. | |
203 bool offscreen_flush_pending_; | |
204 | |
205 // Set to true if the plugin declares that this device will always be opaque. | |
206 // This allows us to do more optimized painting in some cases. | |
207 bool is_always_opaque_; | |
208 | |
209 // Set to the scale between what the plugin considers to be one pixel and one | |
210 // DIP | |
211 float scale_; | |
212 | |
213 base::WeakPtrFactory<PPB_Graphics2D_Impl> weak_ptr_factory_; | |
214 | |
215 friend class content::PepperGraphics2DHost; | |
216 DISALLOW_COPY_AND_ASSIGN(PPB_Graphics2D_Impl); | |
217 }; | |
218 | |
219 } // namespace ppapi | |
220 } // namespace webkit | |
221 | |
222 #endif // WEBKIT_PLUGINS_PPAPI_PPB_GRAPHICS_2D_IMPL_H_ | |
OLD | NEW |