1 /* 2 * Copyright 2012 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef SkSurface_DEFINED 9 #define SkSurface_DEFINED 10 11 #include "SkRefCnt.h" 12 #include "SkImage.h" 13 14 class SkCanvas; 15 class SkPaint; 16 class GrContext; 17 class GrRenderTarget; 18 19 /** 20 * SkSurface represents the backend/results of drawing to a canvas. For raster 21 * drawing, the surface will be pixels, but (for example) when drawing into 22 * a PDF or Picture canvas, the surface stores the recorded commands. 23 * 24 * To draw into a canvas, first create the appropriate type of Surface, and 25 * then request the canvas from the surface. 26 */ 27 class SK_API SkSurface : public SkRefCnt { 28 public: 29 SK_DECLARE_INST_COUNT(SkSurface) 30 31 /** 32 * Create a new surface, using the specified pixels/rowbytes as its 33 * backend. 34 * 35 * If the requested surface cannot be created, or the request is not a 36 * supported configuration, NULL will be returned. 37 */ 38 static SkSurface* NewRasterDirect(const SkImage::Info&, void* pixels, size_t rowBytes); 39 40 /** 41 * Return a new surface, with the memory for the pixels automatically 42 * allocated. 43 * 44 * If the requested surface cannot be created, or the request is not a 45 * supported configuration, NULL will be returned. 46 */ 47 static SkSurface* NewRaster(const SkImage::Info&); 48 49 /** 50 * Return a new surface whose contents will be recorded into a picture. 51 * When this surface is drawn into another canvas, its contents will be 52 * "replayed" into that canvas. 53 */ 54 static SkSurface* NewPicture(int width, int height); 55 56 /** 57 * Return a new surface using the specified render target. 58 */ 59 static SkSurface* NewRenderTargetDirect(GrContext*, GrRenderTarget*); 60 61 /** 62 * Return a new surface whose contents will be drawn to an offscreen 63 * render target, allocated by the surface. 64 */ 65 static SkSurface* NewRenderTarget(GrContext*, const SkImage::Info&, int sampleCount = 0); 66 67 int width() const { return fWidth; } 68 int height() const { return fHeight; } 69 70 /** 71 * Returns a unique non-zero, unique value identifying the content of this 72 * surface. Each time the content is changed changed, either by drawing 73 * into this surface, or explicitly calling notifyContentChanged()) this 74 * method will return a new value. 75 * 76 * If this surface is empty (i.e. has a zero-dimention), this will return 77 * 0. 78 */ 79 uint32_t generationID(); 80 81 /** 82 * Modes that can be passed to notifyContentWillChange 83 */ 84 enum ContentChangeMode { 85 /** 86 * Use this mode if it is known that the upcoming content changes will 87 * clear or overwrite prior contents, thus making them discardable. 88 */ 89 kDiscard_ContentChangeMode, 90 /** 91 * Use this mode if prior surface contents need to be preserved or 92 * if in doubt. 93 */ 94 kRetain_ContentChangeMode, 95 }; 96 97 /** 98 * Call this if the contents are about to change. This will (lazily) force a new 99 * value to be returned from generationID() when it is called next. 100 */ 101 void notifyContentWillChange(ContentChangeMode mode); 102 103 /** 104 * Return a canvas that will draw into this surface. This will always 105 * return the same canvas for a given surface, and is manged/owned by the 106 * surface. It should not be used when its parent surface has gone out of 107 * scope. 108 */ 109 SkCanvas* getCanvas(); 110 111 /** 112 * Return a new surface that is "compatible" with this one, in that it will 113 * efficiently be able to be drawn into this surface. Typical calling 114 * pattern: 115 * 116 * SkSurface* A = SkSurface::New...(); 117 * SkCanvas* canvasA = surfaceA->newCanvas(); 118 * ... 119 * SkSurface* surfaceB = surfaceA->newSurface(...); 120 * SkCanvas* canvasB = surfaceB->newCanvas(); 121 * ... // draw using canvasB 122 * canvasA->drawSurface(surfaceB); // <--- this will always be optimal! 123 */ 124 SkSurface* newSurface(const SkImage::Info&); 125 126 /** 127 * Returns an image of the current state of the surface pixels up to this 128 * point. Subsequent changes to the surface (by drawing into its canvas) 129 * will not be reflected in this image. 130 */ 131 SkImage* newImageSnapshot(); 132 133 /** 134 * Thought the caller could get a snapshot image explicitly, and draw that, 135 * it seems that directly drawing a surface into another canvas might be 136 * a common pattern, and that we could possibly be more efficient, since 137 * we'd know that the "snapshot" need only live until we've handed it off 138 * to the canvas. 139 */ 140 void draw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*); 141 142 protected: 143 SkSurface(int width, int height); 144 145 // called by subclass if their contents have changed 146 void dirtyGenerationID() { 147 fGenerationID = 0; 148 } 149 150 private: 151 const int fWidth; 152 const int fHeight; 153 uint32_t fGenerationID; 154 155 typedef SkRefCnt INHERITED; 156 }; 157 158 #endif 159