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#include "SkSurfaceProps.h" 14 15class SkCanvas; 16class SkPaint; 17class GrContext; 18class GrRenderTarget; 19 20/** 21 * SkSurface represents the backend/results of drawing to a canvas. For raster 22 * drawing, the surface will be pixels, but (for example) when drawing into 23 * a PDF or Picture canvas, the surface stores the recorded commands. 24 * 25 * To draw into a canvas, first create the appropriate type of Surface, and 26 * then request the canvas from the surface. 27 */ 28class SK_API SkSurface : public SkRefCnt { 29public: 30 SK_DECLARE_INST_COUNT(SkSurface) 31 32 /** 33 * Create a new surface, using the specified pixels/rowbytes as its 34 * backend. 35 * 36 * If the requested surface cannot be created, or the request is not a 37 * supported configuration, NULL will be returned. 38 */ 39 static SkSurface* NewRasterDirect(const SkImageInfo&, void* pixels, size_t rowBytes, 40 const SkSurfaceProps* = NULL); 41 42 /** 43 * The same as NewRasterDirect, but also accepts a call-back routine, which is invoked 44 * when the surface is deleted, and is passed the pixel memory and the specified context. 45 */ 46 static SkSurface* NewRasterDirectReleaseProc(const SkImageInfo&, void* pixels, size_t rowBytes, 47 void (*releaseProc)(void* pixels, void* context), 48 void* context, const SkSurfaceProps* = NULL); 49 50 /** 51 * Return a new surface, with the memory for the pixels automatically 52 * allocated. 53 * 54 * If the requested surface cannot be created, or the request is not a 55 * supported configuration, NULL will be returned. 56 */ 57 static SkSurface* NewRaster(const SkImageInfo&, const SkSurfaceProps* = NULL); 58 59 /** 60 * Helper version of NewRaster. It creates a SkImageInfo with the 61 * specified width and height, and populates the rest of info to match 62 * pixels in SkPMColor format. 63 */ 64 static SkSurface* NewRasterPMColor(int width, int height, const SkSurfaceProps* props = NULL) { 65 return NewRaster(SkImageInfo::MakeN32Premul(width, height), props); 66 } 67 68 /** 69 * Return a new surface using the specified render target. 70 */ 71 static SkSurface* NewRenderTargetDirect(GrRenderTarget*, const SkSurfaceProps*); 72 73 static SkSurface* NewRenderTargetDirect(GrRenderTarget* target) { 74 return NewRenderTargetDirect(target, NULL); 75 } 76 77 /** 78 * Return a new surface whose contents will be drawn to an offscreen 79 * render target, allocated by the surface. 80 */ 81 static SkSurface* NewRenderTarget(GrContext*, const SkImageInfo&, int sampleCount, 82 const SkSurfaceProps* = NULL); 83 84 static SkSurface* NewRenderTarget(GrContext* gr, const SkImageInfo& info) { 85 return NewRenderTarget(gr, info, 0, NULL); 86 } 87 88 /** 89 * Return a new surface whose contents will be drawn to an offscreen 90 * render target, allocated by the surface from the scratch texture pool 91 * managed by the GrContext. The scratch texture pool serves the purpose 92 * of retaining textures after they are no longer in use in order to 93 * re-use them later without having to re-allocate. Scratch textures 94 * should be used in cases where high turnover is expected. This allows, 95 * for example, the copy on write to recycle a texture from a recently 96 * released SkImage snapshot of the surface. 97 * Note: Scratch textures count against the GrContext's cached resource 98 * budget. 99 */ 100 static SkSurface* NewScratchRenderTarget(GrContext*, const SkImageInfo&, int sampleCount, 101 const SkSurfaceProps* = NULL); 102 103 static SkSurface* NewScratchRenderTarget(GrContext* gr, const SkImageInfo& info) { 104 return NewScratchRenderTarget(gr, info, 0, NULL); 105 } 106 107#ifdef SK_SUPPORT_LEGACY_TEXTRENDERMODE 108 /** 109 * Text rendering modes that can be passed to NewRenderTarget* 110 */ 111 enum TextRenderMode { 112 /** 113 * This will use the standard text rendering method 114 */ 115 kStandard_TextRenderMode, 116 /** 117 * This will use signed distance fields for text rendering when possible 118 */ 119 kDistanceField_TextRenderMode, 120 }; 121 static SkSurface* NewRenderTargetDirect(GrRenderTarget*, TextRenderMode); 122 static SkSurface* NewRenderTarget(GrContext*, const SkImageInfo&, int sampleCount, 123 TextRenderMode); 124 static SkSurface* NewScratchRenderTarget(GrContext*, const SkImageInfo&, int sampleCount, 125 TextRenderMode); 126#endif 127 128 int width() const { return fWidth; } 129 int height() const { return fHeight; } 130 131 /** 132 * Returns a unique non-zero, unique value identifying the content of this 133 * surface. Each time the content is changed changed, either by drawing 134 * into this surface, or explicitly calling notifyContentChanged()) this 135 * method will return a new value. 136 * 137 * If this surface is empty (i.e. has a zero-dimention), this will return 138 * 0. 139 */ 140 uint32_t generationID(); 141 142 /** 143 * Modes that can be passed to notifyContentWillChange 144 */ 145 enum ContentChangeMode { 146 /** 147 * Use this mode if it is known that the upcoming content changes will 148 * clear or overwrite prior contents, thus making them discardable. 149 */ 150 kDiscard_ContentChangeMode, 151 /** 152 * Use this mode if prior surface contents need to be preserved or 153 * if in doubt. 154 */ 155 kRetain_ContentChangeMode, 156 }; 157 158 /** 159 * Call this if the contents are about to change. This will (lazily) force a new 160 * value to be returned from generationID() when it is called next. 161 */ 162 void notifyContentWillChange(ContentChangeMode mode); 163 164 /** 165 * Return a canvas that will draw into this surface. This will always 166 * return the same canvas for a given surface, and is manged/owned by the 167 * surface. It should not be used when its parent surface has gone out of 168 * scope. 169 */ 170 SkCanvas* getCanvas(); 171 172 /** 173 * Return a new surface that is "compatible" with this one, in that it will 174 * efficiently be able to be drawn into this surface. Typical calling 175 * pattern: 176 * 177 * SkSurface* A = SkSurface::New...(); 178 * SkCanvas* canvasA = surfaceA->newCanvas(); 179 * ... 180 * SkSurface* surfaceB = surfaceA->newSurface(...); 181 * SkCanvas* canvasB = surfaceB->newCanvas(); 182 * ... // draw using canvasB 183 * canvasA->drawSurface(surfaceB); // <--- this will always be optimal! 184 */ 185 SkSurface* newSurface(const SkImageInfo&); 186 187 /** 188 * Returns an image of the current state of the surface pixels up to this 189 * point. Subsequent changes to the surface (by drawing into its canvas) 190 * will not be reflected in this image. 191 */ 192 SkImage* newImageSnapshot(); 193 194 /** 195 * Thought the caller could get a snapshot image explicitly, and draw that, 196 * it seems that directly drawing a surface into another canvas might be 197 * a common pattern, and that we could possibly be more efficient, since 198 * we'd know that the "snapshot" need only live until we've handed it off 199 * to the canvas. 200 */ 201 void draw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*); 202 203 /** 204 * If the surface has direct access to its pixels (i.e. they are in local 205 * RAM) return the const-address of those pixels, and if not null, return 206 * the ImageInfo and rowBytes. The returned address is only valid while 207 * the surface object is in scope, and no API call is made on the surface 208 * or its canvas. 209 * 210 * On failure, returns NULL and the info and rowBytes parameters are 211 * ignored. 212 */ 213 const void* peekPixels(SkImageInfo* info, size_t* rowBytes); 214 215 const SkSurfaceProps& props() const { return fProps; } 216 217protected: 218 SkSurface(int width, int height, const SkSurfaceProps*); 219 SkSurface(const SkImageInfo&, const SkSurfaceProps*); 220 221 // called by subclass if their contents have changed 222 void dirtyGenerationID() { 223 fGenerationID = 0; 224 } 225 226private: 227 const SkSurfaceProps fProps; 228 const int fWidth; 229 const int fHeight; 230 uint32_t fGenerationID; 231 232 typedef SkRefCnt INHERITED; 233}; 234 235#endif 236