Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 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. |
| 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. |
| 15 | namespace pp { |
| 16 | |
| 17 | class CompletionCallback; |
| 18 | class ImageData; |
| 19 | class InstanceHandle; |
| 20 | class Point; |
| 21 | class Rect; |
| 22 | |
| 23 | class 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) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 44 | /// measured in pixels. See <code>SetScale()</code> for more information. |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 45 | /// |
| 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) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 61 | /// It is possible that the destructor does not totally destroy the underlying |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 62 | /// 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) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 77 | /// @return The size of the 2D graphics context measured in pixels. |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 78 | 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) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 263 | /// 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) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 287 | private: |
| 288 | Size size_; |
| 289 | }; |
| 290 | |
| 291 | } // namespace pp |
| 292 | |
| 293 | #endif // PPAPI_CPP_GRAPHICS_2D_H_ |