blob: d4d5c5237ec954d0fbed2b3e8af32b827de62590 [file] [log] [blame]
reed@google.com889b09e2012-07-27 21:10:42 +00001/*
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;
reed@google.com5d4ba882012-07-31 15:45:27 +000016class GrContext;
17class GrRenderTarget;
reed@google.com889b09e2012-07-27 21:10:42 +000018
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 */
junov@chromium.org96447be2013-04-18 13:28:19 +000027class SK_API SkSurface : public SkRefCnt {
reed@google.com889b09e2012-07-27 21:10:42 +000028public:
reed@google.comfd875e82012-08-28 12:43:54 +000029 SK_DECLARE_INST_COUNT(SkSurface)
robertphillips@google.coma22e2112012-08-16 14:58:06 +000030
reed@google.com889b09e2012-07-27 21:10:42 +000031 /**
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 */
mike@reedtribe.orgb9476252012-11-15 02:37:45 +000038 static SkSurface* NewRasterDirect(const SkImage::Info&, void* pixels, size_t rowBytes);
reed@google.com889b09e2012-07-27 21:10:42 +000039
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 */
mike@reedtribe.orgb9476252012-11-15 02:37:45 +000047 static SkSurface* NewRaster(const SkImage::Info&);
reed@google.com889b09e2012-07-27 21:10:42 +000048
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
reed@google.com5d4ba882012-07-31 15:45:27 +000056 /**
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 */
mike@reedtribe.orgb9476252012-11-15 02:37:45 +000065 static SkSurface* NewRenderTarget(GrContext*, const SkImage::Info&, int sampleCount = 0);
reed@google.com5d4ba882012-07-31 15:45:27 +000066
reed@google.com889b09e2012-07-27 21:10:42 +000067 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 */
reed@google.com97af1a62012-08-28 12:19:02 +000079 uint32_t generationID();
rmistry@google.comfbfcd562012-08-23 18:09:54 +000080
reed@google.com889b09e2012-07-27 21:10:42 +000081 /**
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();
rmistry@google.comfbfcd562012-08-23 18:09:54 +000086
reed@google.com889b09e2012-07-27 21:10:42 +000087 /**
reed@google.com9ea5a3b2012-07-30 21:03:46 +000088 * 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.
reed@google.com889b09e2012-07-27 21:10:42 +000092 */
reed@google.com9ea5a3b2012-07-30 21:03:46 +000093 SkCanvas* getCanvas();
reed@google.com889b09e2012-07-27 21:10:42 +000094
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 */
mike@reedtribe.orgb9476252012-11-15 02:37:45 +0000108 SkSurface* newSurface(const SkImage::Info&);
reed@google.com889b09e2012-07-27 21:10:42 +0000109
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 */
junov@chromium.org5ee449a2013-04-12 20:20:50 +0000115 SkImage* newImageSnapshot();
reed@google.com889b09e2012-07-27 21:10:42 +0000116
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
reed@google.com97af1a62012-08-28 12:19:02 +0000129 // called by subclass if their contents have changed
130 void dirtyGenerationID() {
131 fGenerationID = 0;
132 }
133
reed@google.com889b09e2012-07-27 21:10:42 +0000134private:
reed@google.com97af1a62012-08-28 12:19:02 +0000135 const int fWidth;
136 const int fHeight;
137 uint32_t fGenerationID;
skia.committer@gmail.coma27096b2012-08-30 14:38:00 +0000138
reed@google.com7edfb492012-08-28 12:48:35 +0000139 typedef SkRefCnt INHERITED;
reed@google.com889b09e2012-07-27 21:10:42 +0000140};
141
142#endif