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
14class SkCanvas;
15class SkPaint;
16class GrContext;
17class 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 */
27class SK_API SkSurface : public SkRefCnt {
28public:
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     */
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
100    int width() const { return fWidth; }
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
187protected:
188    SkSurface(int width, int height);
189    SkSurface(const SkImageInfo&);
190
191    // called by subclass if their contents have changed
192    void dirtyGenerationID() {
193        fGenerationID = 0;
194    }
195
196private:
197    const int   fWidth;
198    const int   fHeight;
199    uint32_t    fGenerationID;
200
201    typedef SkRefCnt INHERITED;
202};
203
204#endif
205