blob: c6a23905d6f3e0e41dd82570bf1a1457d1215a5e [file] [log] [blame]
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001// 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.
4
5#ifndef PPAPI_CPP_GRAPHICS_2D_H_
6#define PPAPI_CPP_GRAPHICS_2D_H_
7
8#include "ppapi/c/pp_stdint.h"
9#include "ppapi/cpp/resource.h"
10#include "ppapi/cpp/size.h"
11
12
13/// @file
14/// This file defines the API to create a 2D graphics context in the browser.
15namespace pp {
16
17class CompletionCallback;
18class ImageData;
19class InstanceHandle;
20class Point;
21class Rect;
22
23class Graphics2D : public Resource {
24 public:
25 /// Default constructor for creating an is_null() <code>Graphics2D</code>
26 /// object.
27 Graphics2D();
28
29 /// The copy constructor for Graphics2D. The underlying 2D context is not
30 /// copied; this constructor creates another reference to the original 2D
31 /// context.
32 ///
33 /// @param[in] other A pointer to a <code>Graphics2D</code> context.
34 Graphics2D(const Graphics2D& other);
35
36 /// A constructor allocating a new 2D graphics context with the given size
37 /// in the browser, resulting object will be is_null() if the allocation
38 /// failed.
39 ///
40 /// @param[in] instance The instance with which this resource will be
41 /// associated.
42 ///
43 /// @param[in] size The size of the 2D graphics context in the browser,
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010044 /// measured in pixels. See <code>SetScale()</code> for more information.
Torne (Richard Coles)58218062012-11-14 11:43:16 +000045 ///
46 /// @param[in] is_always_opaque Set the <code>is_always_opaque</code> flag
47 /// to true if you know that you will be painting only opaque data to this
48 /// context. This option will disable blending when compositing the module
49 /// with the web page, which might give higher performance on some computers.
50 ///
51 /// If you set <code>is_always_opaque</code>, your alpha channel should
52 /// always be set to 0xFF or there may be painting artifacts. The alpha values
53 /// overwrite the destination alpha values without blending when
54 /// <code>is_always_opaque</code> is true.
55 Graphics2D(const InstanceHandle& instance,
56 const Size& size,
57 bool is_always_opaque);
58
59 /// A destructor that decrements the reference count of a
60 /// <code>Graphics2D</code> object made using the previous copy constructor.
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010061 /// It is possible that the destructor does not totally destroy the underlying
Torne (Richard Coles)58218062012-11-14 11:43:16 +000062 /// 2D context if there are outstanding references to it.
63 virtual ~Graphics2D();
64
65 /// This function assigns one 2D graphics context to this 2D graphics
66 /// context. This function increases the reference count of the 2D resource
67 /// of the other 2D graphics context while decrementing the reference counter
68 /// of this 2D graphics context.
69 ///
70 /// @param[in] other An other 2D graphics context.
71 ///
72 /// @return A new Graphics2D context.
73 Graphics2D& operator=(const Graphics2D& other);
74
75 /// Getter function for returning size of the 2D graphics context.
76 ///
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010077 /// @return The size of the 2D graphics context measured in pixels.
Torne (Richard Coles)58218062012-11-14 11:43:16 +000078 const Size& size() const { return size_; }
79
80 /// PaintImageData() enqueues a paint command of the given image into
81 /// the context. This command has no effect until you call Flush(). As a
82 /// result, what counts is the contents of the bitmap when you call Flush,
83 /// not when you call this function.
84 ///
85 /// The provided image will be placed at <code>top_left</code> from the top
86 /// left of the context's internal backing store. This version of
87 /// PaintImageData paints the entire image. Refer to the other version of
88 /// this function to paint only part of the area.
89 ///
90 /// The painted area of the source bitmap must fall entirely within the
91 /// context. Attempting to paint outside of the context will result in an
92 /// error.
93 ///
94 /// There are two methods most modules will use for painting. The first
95 /// method is to generate a new <code>ImageData</code> and then paint it.
96 /// In this case, you'll set the location of your painting to
97 /// <code>top_left</code> and set <code>src_rect</code> to <code>NULL</code>.
98 /// The second is that you're generating small invalid regions out of a larger
99 /// bitmap representing your entire module's image.
100 ///
101 /// @param[in] image The <code>ImageData</code> to be painted.
102 /// @param[in] top_left A <code>Point</code> representing the
103 /// <code>top_left</code> location where the <code>ImageData</code> will be
104 /// painted.
105 void PaintImageData(const ImageData& image,
106 const Point& top_left);
107
108 /// PaintImageData() enqueues a paint command of the given image into
109 /// the context. This command has no effect until you call Flush(). As a
110 /// result, what counts is the contents of the bitmap when you call Flush(),
111 /// not when you call this function.
112 ///
113 /// The provided image will be placed at <code>top_left</code> from the top
114 /// left of the context's internal backing store. Then the pixels contained
115 /// in <code>src_rect</code> will be copied into the backing store. This
116 /// means that the rectangle being painted will be at <code>src_rect</code>
117 /// offset by <code>top_left</code>.
118 ///
119 /// The <code>src_rect</code> is specified in the coordinate system of the
120 /// image being painted, not the context. For the common case of copying the
121 /// entire image, you may specify an empty <code>src_rect</code>.
122 ///
123 /// The painted area of the source bitmap must fall entirely within the
124 /// context. Attempting to paint outside of the context will result in an
125 /// error. However, the source bitmap may fall outside the context, as long
126 /// as the <code>src_rect</code> subset of it falls entirely within the
127 /// context.
128 ///
129 /// There are two methods most modules will use for painting. The first
130 /// method is to generate a new <code>ImageData</code> and then paint it. In
131 /// this case, you'll set the location of your painting to
132 /// <code>top_left</code> and set <code>src_rect</code> to <code>NULL</code>.
133 /// The second is that you're generating small invalid regions out of a larger
134 /// bitmap representing your entire module. In this case, you would set the
135 /// location of your image to (0,0) and then set <code>src_rect</code> to the
136 /// pixels you changed.
137 ///
138 /// @param[in] image The <code>ImageData</code> to be painted.
139 /// @param[in] top_left A <code>Point</code> representing the
140 /// <code>top_left</code> location where the <code>ImageData</code> will be
141 /// painted.
142 /// @param[in] src_rect The rectangular area where the <code>ImageData</code>
143 /// will be painted.
144 void PaintImageData(const ImageData& image,
145 const Point& top_left,
146 const Rect& src_rect);
147
148 /// Scroll() enqueues a scroll of the context's backing store. This
149 /// function has no effect until you call Flush(). The data within the
150 /// provided clipping rectangle will be shifted by (dx, dy) pixels.
151 ///
152 /// This function will result in some exposed region which will have
153 /// undefined contents. The module should call PaintImageData() on
154 /// these exposed regions to give the correct contents.
155 ///
156 /// The scroll can be larger than the area of the clipping rectangle, which
157 /// means the current image will be scrolled out of the rectangle. This
158 /// scenario is not an error but will result in a no-op.
159 ///
160 /// @param[in] clip The clipping rectangle.
161 /// @param[in] amount The amount the area in the clipping rectangle will
162 /// shifted.
163 void Scroll(const Rect& clip, const Point& amount);
164
165 /// ReplaceContents() provides a slightly more efficient way to paint the
166 /// entire module's image. Normally, calling PaintImageData() requires that
167 /// the browser copy the pixels out of the image and into the graphics
168 /// context's backing store. This function replaces the graphics context's
169 /// backing store with the given image, avoiding the copy.
170 ///
171 /// The new image must be the exact same size as this graphics context. If
172 /// the new image uses a different image format than the browser's native
173 /// bitmap format (use ImageData::GetNativeImageDataFormat() to retrieve the
174 /// format), then a conversion will be done inside the browser which may slow
175 /// the performance a little bit.
176 ///
177 /// <strong>Note:</strong> The new image will not be painted until you call
178 /// Flush().
179 ///
180 /// After this call, you should take care to release your references to the
181 /// image. If you paint to the image after ReplaceContents(), there is the
182 /// possibility of significant painting artifacts because the page might use
183 /// partially-rendered data when copying out of the backing store.
184 ///
185 /// In the case of an animation, you will want to allocate a new image for
186 /// the next frame. It is best if you wait until the flush callback has
187 /// executed before allocating this bitmap. This gives the browser the option
188 /// of caching the previous backing store and handing it back to you
189 /// (assuming the sizes match). In the optimal case, this means no bitmaps are
190 /// allocated during the animation, and the backing store and "front buffer"
191 /// (which the module is painting into) are just being swapped back and forth.
192 ///
193 /// @param[in] image The <code>ImageData</code> to be painted.
194 void ReplaceContents(ImageData* image);
195
196 /// Flush() flushes any enqueued paint, scroll, and replace commands
197 /// to the backing store. This actually executes the updates, and causes a
198 /// repaint of the webpage, assuming this graphics context is bound to a
199 /// module instance.
200 ///
201 /// Flush() runs in asynchronous mode. Specify a callback function and
202 /// the argument for that callback function. The callback function will be
203 /// executed on the calling thread when the image has been painted to the
204 /// screen. While you are waiting for a <code>Flush</code> callback,
205 /// additional calls to Flush() will fail.
206 ///
207 /// Because the callback is executed (or thread unblocked) only when the
208 /// module's image is actually on the screen, this function provides
209 /// a way to rate limit animations. By waiting until the image is on the
210 /// screen before painting the next frame, you can ensure you're not
211 /// flushing 2D graphics faster than the screen can be updated.
212 ///
213 /// <strong>Unbound contexts</strong>
214 /// If the context is not bound to a module instance, you will
215 /// still get a callback. The callback will execute after Flush() returns
216 /// to avoid reentrancy. The callback will not wait until anything is
217 /// painted to the screen because there will be nothing on the screen. The
218 /// timing of this callback is not guaranteed and may be deprioritized by
219 /// the browser because it is not affecting the user experience.
220 ///
221 /// <strong>Off-screen instances</strong>
222 /// If the context is bound to an instance that is
223 /// currently not visible (for example, scrolled out of view) it will
224 /// behave like the "unbound context" case.
225 ///
226 /// <strong>Detaching a context</strong>
227 /// If you detach a context from a module instance, any
228 /// pending flush callbacks will be converted into the "unbound context"
229 /// case.
230 ///
231 /// <strong>Released contexts</strong>
232 /// A callback may or may not still get called even if you have released all
233 /// of your references to the context. This can occur if there are internal
234 /// references to the context that means it has not been internally
235 /// destroyed (for example, if it is still bound to an instance) or due to
236 /// other implementation details. As a result, you should be careful to
237 /// check that flush callbacks are for the context you expect and that
238 /// you're capable of handling callbacks for context that you may have
239 /// released your reference to.
240 ///
241 /// <strong>Shutdown</strong>
242 /// If a module instance is removed when a Flush is pending, the
243 /// callback will not be executed.
244 ///
245 /// @param[in] cc A <code>CompletionCallback</code> to be called when the
246 /// image has been painted on the screen.
247 ///
248 /// @return Returns <code>PP_OK</code> on success or
249 /// <code>PP_ERROR_BADRESOURCE</code> if the graphics context is invalid,
250 /// <code>PP_ERROR_BADARGUMENT</code> if the callback is null and
251 /// flush is being called from the main thread of the module, or
252 /// <code>PP_ERROR_INPROGRESS</code> if a flush is already pending that has
253 /// not issued its callback yet. In the failure case, nothing will be
254 /// updated and no callback will be scheduled.
255
256 // TODO(darin): We should ensure that the completion callback always runs, so
257 // that it is easier for consumers to manage memory referenced by a callback.
258
259 // TODO(): Add back in the synchronous mode description once we have support
260 // for it.
261 int32_t Flush(const CompletionCallback& cc);
262
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100263 /// SetScale() sets the scale factor that will be applied when painting the
264 /// graphics context onto the output device. Typically, if rendering at device
265 /// resolution is desired, the context would be created with the width and
266 /// height scaled up by the view's GetDeviceScale and SetScale called with a
267 /// scale of 1.0 / GetDeviceScale(). For example, if the view resource passed
268 /// to DidChangeView has a rectangle of (w=200, h=100) and a device scale of
269 /// 2.0, one would call Create with a size of (w=400, h=200) and then call
270 /// SetScale with 0.5. One would then treat each pixel in the context as a
271 /// single device pixel.
272 ///
273 /// @param[in] scale The scale to apply when painting.
274 ///
275 /// @return Returns <code>true</code> on success or <code>false</code>
276 /// if the resource is invalid or the scale factor is 0 or less.
277 bool SetScale(float scale);
278
279 /// GetScale() gets the scale factor that will be applied when painting the
280 /// graphics context onto the output device.
281 ///
282 /// @return Returns the scale factor for the graphics context. If the resource
283 /// is invalid, 0.0 will be returned. The default scale for a graphics context
284 /// is 1.0.
285 float GetScale();
286
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000287 private:
288 Size size_;
289};
290
291} // namespace pp
292
293#endif // PPAPI_CPP_GRAPHICS_2D_H_