github.com/razvanm/vanadium-go-1.3@v0.0.0-20160721203343-4a65068e5915/src/runtime/ppapi/graphics2D_nacl.go (about) 1 // Copyright 2014 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package ppapi 6 7 import ( 8 "errors" 9 ) 10 11 // Graphics2D represents a 2D graphics context. The context must be bound to an 12 // Instance, using BindGraphics2D(), for the drawing to be visible. 13 type Graphics2D struct { 14 Resource 15 } 16 17 var ( 18 errBindFailed = errors.New("graphics bind failed") 19 errGraphics2DCreateFailed = errors.New("graphics2D creation failed") 20 errGraphics2DContext = errors.New("graphics2D context error") 21 errGraphics2DOperationFailed = errors.New("graphics2D operation failed") 22 ) 23 24 // NewGraphics2D returns a new Graphics2D instance. 25 func (inst Instance) NewGraphics2D(size Size, isAlwaysOpaque bool) (g Graphics2D, err error) { 26 rid := ppb_graphics2d_create(inst.id, &size, toPPBool(isAlwaysOpaque)) 27 if rid == 0 { 28 err = errGraphics2DCreateFailed 29 return 30 } 31 g.id = rid 32 return 33 } 34 35 // BindGraphics2D binds the Graphics2D context to the Instance. 36 func (inst Instance) BindGraphics2D(g Graphics2D) error { 37 b := ppb_instance_bind_graphics(inst.id, g.id) 38 if b == 0 { 39 return errBindFailed 40 } 41 return nil 42 } 43 44 // Describe returns the size and opacity of the graphics 2D context. 45 func (g Graphics2D) Describe() (size Size, isAlwaysOpaque bool, err error) { 46 var b pp_Bool 47 ok := ppb_graphics2d_describe(g.id, &size, &b) 48 if ok == 0 { 49 err = errGraphics2DContext 50 return 51 } 52 isAlwaysOpaque = b != 0 53 err = nil 54 return 55 } 56 57 // Scroll enqueues a scroll of the context's backing store. This function has no 58 // effect until you call Flush(). The data within the provided clipping 59 // rectangle will be shifted by (dx, dy) pixels. 60 // 61 // This function will result in some exposed region which will have undefined 62 // contents. The module should call PaintImageData() on these exposed regions to 63 // give the correct contents. 64 // 65 // The scroll can be larger than the area of the clipping rectangle, which means 66 // the current image will be scrolled out of the rectangle. This scenario is not 67 // an error but will result in a no-op. 68 func (g Graphics2D) Scroll(clipRect Rect, amount Point) { 69 ppb_graphics2d_scroll(g.id, &clipRect, &amount) 70 } 71 72 // GetScale returns the scale factor that will be applied when painting the 73 // graphics context onto the output device. 74 func (g Graphics2D) GetScale() float32 { 75 return ppb_graphics2d_get_scale(g.id) 76 } 77 78 // SetScale sets the scale factor that will be applied when painting the 79 // graphics context onto the output device. 80 // 81 // Typically, if rendering at device resolution is desired, the context would be 82 // created with the width and height scaled up by the view's GetDeviceScale and 83 // SetScale called with a scale of 1.0 / GetDeviceScale(). For example, if the 84 // view resource passed to DidChangeView has a rectangle of (w=200, h=100) and a 85 // device scale of 2.0, one would call Create with a size of (w=400, h=200) and 86 // then call SetScale with 0.5. One would then treat each pixel in the context 87 // as a single device pixel. 88 func (g Graphics2D) SetScale(scale float32) error { 89 b := ppb_graphics2d_set_scale(g.id, scale) 90 if b == ppFalse { 91 return errGraphics2DOperationFailed 92 } 93 return nil 94 } 95 96 // PaintImageData() enqueues a paint of the given image into the context. 97 // 98 // This function has no effect until you call Flush() As a result, what counts 99 // is the contents of the bitmap when you call Flush(), not when you call this 100 // function. 101 // 102 // The provided image will be placed at top_left from the top left of the 103 // context's internal backing store. Then the pixels contained in src_rect will 104 // be copied into the backing store. This means that the rectangle being painted 105 // will be at src_rect offset by top_left. 106 // 107 // The src_rect is specified in the coordinate system of the image being 108 // painted, not the context. For the common case of copying the entire image, 109 // you may specify an empty src_rect. 110 // 111 // The painted area of the source bitmap must fall entirely within the 112 // context. Attempting to paint outside of the context will result in an 113 // error. However, the source bitmap may fall outside the context, as long as 114 // the src_rect subset of it falls entirely within the context. 115 // 116 // There are two methods most modules will use for painting. The first method is 117 // to generate a new ImageData and then paint it. In this case, you'll set the 118 // location of your painting to top_left and set src_rect to NULL. The second is 119 // that you're generating small invalid regions out of a larger bitmap 120 // representing your entire instance. In this case, you would set the location 121 // of your image to (0,0) and then set src_rect to the pixels you changed. 122 func (g Graphics2D) PaintImageData(data ImageData, topLeft Point, src *Rect) { 123 ppb_graphics2d_paint_image_data(g.id, data.id, &topLeft, src) 124 } 125 126 // ReplaceContents provides a slightly more efficient way to paint the entire 127 // module's image. 128 // 129 // Normally, calling PaintImageData() requires that the browser copy the pixels 130 // out of the image and into the graphics context's backing store. This function 131 // replaces the graphics context's backing store with the given image, avoiding 132 // the copy. 133 // 134 // The new image must be the exact same size as this graphics context. If the 135 // new image uses a different image format than the browser's native bitmap 136 // format (use PPB_ImageData.GetNativeImageDataFormat() to retrieve the format), 137 // then a conversion will be done inside the browser which may slow the 138 // performance a little bit. 139 // 140 // Note: The new image will not be painted until you call Flush(). 141 // 142 // After this call, you should take care to release your references to the 143 // image. If you paint to the image after ReplaceContents(), there is the 144 // possibility of significant painting artifacts because the page might use 145 // partially-rendered data when copying out of the backing store. 146 // 147 // In the case of an animation, you will want to allocate a new image for the 148 // next frame. It is best if you wait until the flush callback has executed 149 // before allocating this bitmap. This gives the browser the option of caching 150 // the previous backing store and handing it back to you (assuming the sizes 151 // match). In the optimal case, this means no bitmaps are allocated during the 152 // animation, and the backing store and "front buffer" (which the plugin is 153 // painting into) are just being swapped back and forth. 154 func (g Graphics2D) ReplaceContents(data ImageData) { 155 ppb_graphics2d_replace_contents(g.id, data.id) 156 } 157 158 // Flush flushes any enqueued paint, scroll, and replace commands to the 159 // backing store. 160 // 161 // This function actually executes the updates, and causes a repaint of the 162 // webpage, assuming this graphics context is bound to a module instance. 163 // 164 // Flush() runs in asynchronous mode. Specify a callback function and the 165 // argument for that callback function. The callback function will be executed 166 // on the calling thread when the image has been painted to the screen. While 167 // you are waiting for a flush callback, additional calls to Flush() will fail. 168 // 169 // Because the callback is executed (or thread unblocked) only when the 170 // instance's image is actually on the screen, this function provides a way to 171 // rate limit animations. By waiting until the image is on the screen before 172 // painting the next frame, you can ensure you're not flushing 2D graphics 173 // faster than the screen can be updated. 174 // 175 // Unbound contexts If the context is not bound to a module instance, you will 176 // still get a callback. The callback will execute after Flush() returns to 177 // avoid reentrancy. The callback will not wait until anything is painted to the 178 // screen because there will be nothing on the screen. The timing of this 179 // callback is not guaranteed and may be deprioritized by the browser because it 180 // is not affecting the user experience. 181 // 182 // Off-screen instances If the context is bound to an instance that is currently 183 // not visible (for example, scrolled out of view) it will behave like the 184 // "unbound context" case. 185 // 186 // Detaching a context If you detach a context from a module instance, any 187 // pending flush callbacks will be converted into the "unbound context" case. 188 // 189 // Released contexts A callback may or may not get called even if you have 190 // released all of your references to the context. This scenario can occur if 191 // there are internal references to the context suggesting it has not been 192 // internally destroyed (for example, if it is still bound to an instance) or 193 // due to other implementation details. As a result, you should be careful to 194 // check that flush callbacks are for the context you expect and that you're 195 // capable of handling callbacks for unreferenced contexts. 196 // 197 // Shutdown If a module instance is removed when a flush is pending, the 198 // callback will not be executed. 199 func (g Graphics2D) Flush() error { 200 code := ppb_graphics2d_flush(g.id, ppNullCompletionCallback) 201 return decodeError(Error(code)) 202 }