SkSurface.h revision 96447bef11a88e5a6c5bb3223133a73db87ca87a
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 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     *  Call this if the contents have changed. This will (lazily) force a new
83     *  value to be returned from generationID() when it is called next.
84     */
85    void notifyContentChanged();
86
87    /**
88     *  Return a canvas that will draw into this surface. This will always
89     *  return the same canvas for a given surface, and is manged/owned by the
90     *  surface. It should not be used when its parent surface has gone out of
91     *  scope.
92     */
93    SkCanvas* getCanvas();
94
95    /**
96     *  Return a new surface that is "compatible" with this one, in that it will
97     *  efficiently be able to be drawn into this surface. Typical calling
98     *  pattern:
99     *
100     *  SkSurface* A = SkSurface::New...();
101     *  SkCanvas* canvasA = surfaceA->newCanvas();
102     *  ...
103     *  SkSurface* surfaceB = surfaceA->newSurface(...);
104     *  SkCanvas* canvasB = surfaceB->newCanvas();
105     *  ... // draw using canvasB
106     *  canvasA->drawSurface(surfaceB); // <--- this will always be optimal!
107     */
108    SkSurface* newSurface(const SkImage::Info&);
109
110    /**
111     *  Returns an image of the current state of the surface pixels up to this
112     *  point. Subsequent changes to the surface (by drawing into its canvas)
113     *  will not be reflected in this image.
114     */
115    SkImage* newImageSnapshot();
116
117    /**
118     *  Thought the caller could get a snapshot image explicitly, and draw that,
119     *  it seems that directly drawing a surface into another canvas might be
120     *  a common pattern, and that we could possibly be more efficient, since
121     *  we'd know that the "snapshot" need only live until we've handed it off
122     *  to the canvas.
123     */
124    void draw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*);
125
126protected:
127    SkSurface(int width, int height);
128
129    // called by subclass if their contents have changed
130    void dirtyGenerationID() {
131        fGenerationID = 0;
132    }
133
134private:
135    const int   fWidth;
136    const int   fHeight;
137    uint32_t    fGenerationID;
138
139    typedef SkRefCnt INHERITED;
140};
141
142#endif
143