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 return NewRaster(SkImageInfo::MakeN32Premul(width, height)); 56 } 57 58 /** 59 * Text rendering modes that can be passed to NewRenderTarget* 60 */ 61 enum TextRenderMode { 62 /** 63 * This will use the standard text rendering method 64 */ 65 kStandard_TextRenderMode, 66 /** 67 * This will use signed distance fields for text rendering when possible 68 */ 69 kDistanceField_TextRenderMode, 70 }; 71 72 /** 73 * Return a new surface using the specified render target. 74 */ 75 static SkSurface* NewRenderTargetDirect(GrRenderTarget*, 76 TextRenderMode trm = kStandard_TextRenderMode); 77 78 /** 79 * Return a new surface whose contents will be drawn to an offscreen 80 * render target, allocated by the surface. 81 */ 82 static SkSurface* NewRenderTarget(GrContext*, const SkImageInfo&, int sampleCount = 0, 83 TextRenderMode trm = kStandard_TextRenderMode); 84 85 /** 86 * Return a new surface whose contents will be drawn to an offscreen 87 * render target, allocated by the surface from the scratch texture pool 88 * managed by the GrContext. The scratch texture pool serves the purpose 89 * of retaining textures after they are no longer in use in order to 90 * re-use them later without having to re-allocate. Scratch textures 91 * should be used in cases where high turnover is expected. This allows, 92 * for example, the copy on write to recycle a texture from a recently 93 * released SkImage snapshot of the surface. 94 * Note: Scratch textures count against the GrContext's cached resource 95 * budget. 96 */ 97 static SkSurface* NewScratchRenderTarget(GrContext*, const SkImageInfo&, int sampleCount = 0, 98 TextRenderMode trm = kStandard_TextRenderMode); 99 width()100 int width() const { return fWidth; } height()101 int height() const { return fHeight; } 102 103 /** 104 * Returns a unique non-zero, unique value identifying the content of this 105 * surface. Each time the content is changed changed, either by drawing 106 * into this surface, or explicitly calling notifyContentChanged()) this 107 * method will return a new value. 108 * 109 * If this surface is empty (i.e. has a zero-dimention), this will return 110 * 0. 111 */ 112 uint32_t generationID(); 113 114 /** 115 * Modes that can be passed to notifyContentWillChange 116 */ 117 enum ContentChangeMode { 118 /** 119 * Use this mode if it is known that the upcoming content changes will 120 * clear or overwrite prior contents, thus making them discardable. 121 */ 122 kDiscard_ContentChangeMode, 123 /** 124 * Use this mode if prior surface contents need to be preserved or 125 * if in doubt. 126 */ 127 kRetain_ContentChangeMode, 128 }; 129 130 /** 131 * Call this if the contents are about to change. This will (lazily) force a new 132 * value to be returned from generationID() when it is called next. 133 */ 134 void notifyContentWillChange(ContentChangeMode mode); 135 136 /** 137 * Return a canvas that will draw into this surface. This will always 138 * return the same canvas for a given surface, and is manged/owned by the 139 * surface. It should not be used when its parent surface has gone out of 140 * scope. 141 */ 142 SkCanvas* getCanvas(); 143 144 /** 145 * Return a new surface that is "compatible" with this one, in that it will 146 * efficiently be able to be drawn into this surface. Typical calling 147 * pattern: 148 * 149 * SkSurface* A = SkSurface::New...(); 150 * SkCanvas* canvasA = surfaceA->newCanvas(); 151 * ... 152 * SkSurface* surfaceB = surfaceA->newSurface(...); 153 * SkCanvas* canvasB = surfaceB->newCanvas(); 154 * ... // draw using canvasB 155 * canvasA->drawSurface(surfaceB); // <--- this will always be optimal! 156 */ 157 SkSurface* newSurface(const SkImageInfo&); 158 159 /** 160 * Returns an image of the current state of the surface pixels up to this 161 * point. Subsequent changes to the surface (by drawing into its canvas) 162 * will not be reflected in this image. 163 */ 164 SkImage* newImageSnapshot(); 165 166 /** 167 * Thought the caller could get a snapshot image explicitly, and draw that, 168 * it seems that directly drawing a surface into another canvas might be 169 * a common pattern, and that we could possibly be more efficient, since 170 * we'd know that the "snapshot" need only live until we've handed it off 171 * to the canvas. 172 */ 173 void draw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*); 174 175 /** 176 * If the surface has direct access to its pixels (i.e. they are in local 177 * RAM) return the const-address of those pixels, and if not null, return 178 * the ImageInfo and rowBytes. The returned address is only valid while 179 * the surface object is in scope, and no API call is made on the surface 180 * or its canvas. 181 * 182 * On failure, returns NULL and the info and rowBytes parameters are 183 * ignored. 184 */ 185 const void* peekPixels(SkImageInfo* info, size_t* rowBytes); 186 187 protected: 188 SkSurface(int width, int height); 189 SkSurface(const SkImageInfo&); 190 191 // called by subclass if their contents have changed dirtyGenerationID()192 void dirtyGenerationID() { 193 fGenerationID = 0; 194 } 195 196 private: 197 const int fWidth; 198 const int fHeight; 199 uint32_t fGenerationID; 200 201 typedef SkRefCnt INHERITED; 202 }; 203 204 #endif 205