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 SkImageInfo&, 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 SkImageInfo&); 48 49 /** 50 * Helper version of NewRaster. It creates a SkImageInfo with the 51 * specified width and height, and populates the rest of info to match 52 * pixels in SkPMColor format. 53 */ NewRasterPMColor(int width,int height)54 static SkSurface* NewRasterPMColor(int width, int height) { 55 SkImageInfo info = { 56 width, height, kPMColor_SkColorType, kPremul_SkAlphaType 57 }; 58 return NewRaster(info); 59 } 60 61 /** 62 * Return a new surface whose contents will be recorded into a picture. 63 * When this surface is drawn into another canvas, its contents will be 64 * "replayed" into that canvas. 65 */ 66 static SkSurface* NewPicture(int width, int height); 67 68 /** 69 * Return a new surface using the specified render target. 70 */ 71 static SkSurface* NewRenderTargetDirect(GrContext*, GrRenderTarget*); 72 73 /** 74 * Return a new surface whose contents will be drawn to an offscreen 75 * render target, allocated by the surface. 76 */ 77 static SkSurface* NewRenderTarget(GrContext*, const SkImageInfo&, int sampleCount = 0); 78 width()79 int width() const { return fWidth; } height()80 int height() const { return fHeight; } 81 82 /** 83 * Returns a unique non-zero, unique value identifying the content of this 84 * surface. Each time the content is changed changed, either by drawing 85 * into this surface, or explicitly calling notifyContentChanged()) this 86 * method will return a new value. 87 * 88 * If this surface is empty (i.e. has a zero-dimention), this will return 89 * 0. 90 */ 91 uint32_t generationID(); 92 93 /** 94 * Modes that can be passed to notifyContentWillChange 95 */ 96 enum ContentChangeMode { 97 /** 98 * Use this mode if it is known that the upcoming content changes will 99 * clear or overwrite prior contents, thus making them discardable. 100 */ 101 kDiscard_ContentChangeMode, 102 /** 103 * Use this mode if prior surface contents need to be preserved or 104 * if in doubt. 105 */ 106 kRetain_ContentChangeMode, 107 }; 108 109 /** 110 * Call this if the contents are about to change. This will (lazily) force a new 111 * value to be returned from generationID() when it is called next. 112 */ 113 void notifyContentWillChange(ContentChangeMode mode); 114 115 /** 116 * Return a canvas that will draw into this surface. This will always 117 * return the same canvas for a given surface, and is manged/owned by the 118 * surface. It should not be used when its parent surface has gone out of 119 * scope. 120 */ 121 SkCanvas* getCanvas(); 122 123 /** 124 * Return a new surface that is "compatible" with this one, in that it will 125 * efficiently be able to be drawn into this surface. Typical calling 126 * pattern: 127 * 128 * SkSurface* A = SkSurface::New...(); 129 * SkCanvas* canvasA = surfaceA->newCanvas(); 130 * ... 131 * SkSurface* surfaceB = surfaceA->newSurface(...); 132 * SkCanvas* canvasB = surfaceB->newCanvas(); 133 * ... // draw using canvasB 134 * canvasA->drawSurface(surfaceB); // <--- this will always be optimal! 135 */ 136 SkSurface* newSurface(const SkImageInfo&); 137 138 /** 139 * Returns an image of the current state of the surface pixels up to this 140 * point. Subsequent changes to the surface (by drawing into its canvas) 141 * will not be reflected in this image. 142 */ 143 SkImage* newImageSnapshot(); 144 145 /** 146 * Thought the caller could get a snapshot image explicitly, and draw that, 147 * it seems that directly drawing a surface into another canvas might be 148 * a common pattern, and that we could possibly be more efficient, since 149 * we'd know that the "snapshot" need only live until we've handed it off 150 * to the canvas. 151 */ 152 void draw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*); 153 154 protected: 155 SkSurface(int width, int height); 156 157 // called by subclass if their contents have changed dirtyGenerationID()158 void dirtyGenerationID() { 159 fGenerationID = 0; 160 } 161 162 private: 163 const int fWidth; 164 const int fHeight; 165 uint32_t fGenerationID; 166 167 typedef SkRefCnt INHERITED; 168 }; 169 170 #endif 171