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, 44 /// measured in pixels. See <code>SetScale()</code> for more information. 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. 61 /// It is possible that the destructor does not totally destroy the underlying 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 /// 77 /// @return The size of the 2D graphics context measured in pixels. size()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 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 287 private: 288 Size size_; 289 }; 290 291 } // namespace pp 292 293 #endif // PPAPI_CPP_GRAPHICS_2D_H_ 294