1889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com/*
2889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com * Copyright 2012 Google Inc.
3889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com *
4889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com * Use of this source code is governed by a BSD-style license that can be
5889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com * found in the LICENSE file.
6889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com */
7889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com
8889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com#ifndef SkSurface_DEFINED
9889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com#define SkSurface_DEFINED
10889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com
11889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com#include "SkRefCnt.h"
12889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com#include "SkImage.h"
13889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com
14889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.comclass SkCanvas;
15889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.comclass SkPaint;
165d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.comclass GrContext;
175d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.comclass GrRenderTarget;
18889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com
19889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com/**
20889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com *  SkSurface represents the backend/results of drawing to a canvas. For raster
21889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com *  drawing, the surface will be pixels, but (for example) when drawing into
22889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com *  a PDF or Picture canvas, the surface stores the recorded commands.
23889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com *
24889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com *  To draw into a canvas, first create the appropriate type of Surface, and
25889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com *  then request the canvas from the surface.
26889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com */
2796447bef11a88e5a6c5bb3223133a73db87ca87ajunov@chromium.orgclass SK_API SkSurface : public SkRefCnt {
28889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.compublic:
29fd875e80142c5c494ab95f0885b78e8a8ffc8716reed@google.com    SK_DECLARE_INST_COUNT(SkSurface)
30a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com
31889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com    /**
32889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com     *  Create a new surface, using the specified pixels/rowbytes as its
33889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com     *  backend.
34889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com     *
35889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com     *  If the requested surface cannot be created, or the request is not a
36889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com     *  supported configuration, NULL will be returned.
37889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com     */
382bd8b8100529c96c81c30f749f672f4caf775b04reed@google.com    static SkSurface* NewRasterDirect(const SkImageInfo&, void* pixels, size_t rowBytes);
39889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com
40889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com    /**
41889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com     *  Return a new surface, with the memory for the pixels automatically
42889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com     *  allocated.
43889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com     *
44889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com     *  If the requested surface cannot be created, or the request is not a
45889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com     *  supported configuration, NULL will be returned.
46889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com     */
472bd8b8100529c96c81c30f749f672f4caf775b04reed@google.com    static SkSurface* NewRaster(const SkImageInfo&);
48889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com
49889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com    /**
502bd8b8100529c96c81c30f749f672f4caf775b04reed@google.com     *  Helper version of NewRaster. It creates a SkImageInfo with the
51636d87a3f411507020a21c6b0641da795eb5d275reed@google.com     *  specified width and height, and populates the rest of info to match
52636d87a3f411507020a21c6b0641da795eb5d275reed@google.com     *  pixels in SkPMColor format.
53636d87a3f411507020a21c6b0641da795eb5d275reed@google.com     */
54636d87a3f411507020a21c6b0641da795eb5d275reed@google.com    static SkSurface* NewRasterPMColor(int width, int height) {
552c56cb858f9227599746828d1a06b1b1588b44f0bungeman@google.com        return NewRaster(SkImageInfo::MakeN32Premul(width, height));
56636d87a3f411507020a21c6b0641da795eb5d275reed@google.com    }
57636d87a3f411507020a21c6b0641da795eb5d275reed@google.com
58636d87a3f411507020a21c6b0641da795eb5d275reed@google.com    /**
596fcd1ef244f50b382627cdc7cdb50eb9e2dd46ebcommit-bot@chromium.org     *  Text rendering modes that can be passed to NewRenderTarget*
606fcd1ef244f50b382627cdc7cdb50eb9e2dd46ebcommit-bot@chromium.org     */
616fcd1ef244f50b382627cdc7cdb50eb9e2dd46ebcommit-bot@chromium.org    enum TextRenderMode {
626fcd1ef244f50b382627cdc7cdb50eb9e2dd46ebcommit-bot@chromium.org        /**
636fcd1ef244f50b382627cdc7cdb50eb9e2dd46ebcommit-bot@chromium.org         *  This will use the standard text rendering method
646fcd1ef244f50b382627cdc7cdb50eb9e2dd46ebcommit-bot@chromium.org         */
656fcd1ef244f50b382627cdc7cdb50eb9e2dd46ebcommit-bot@chromium.org        kStandard_TextRenderMode,
666fcd1ef244f50b382627cdc7cdb50eb9e2dd46ebcommit-bot@chromium.org        /**
676fcd1ef244f50b382627cdc7cdb50eb9e2dd46ebcommit-bot@chromium.org         *  This will use signed distance fields for text rendering when possible
686fcd1ef244f50b382627cdc7cdb50eb9e2dd46ebcommit-bot@chromium.org         */
696fcd1ef244f50b382627cdc7cdb50eb9e2dd46ebcommit-bot@chromium.org        kDistanceField_TextRenderMode,
706fcd1ef244f50b382627cdc7cdb50eb9e2dd46ebcommit-bot@chromium.org    };
716fcd1ef244f50b382627cdc7cdb50eb9e2dd46ebcommit-bot@chromium.org
726fcd1ef244f50b382627cdc7cdb50eb9e2dd46ebcommit-bot@chromium.org    /**
73372b7a4f565354d2101092c6bac6f9550ad506fdreed@google.com     *  Return a new surface using the specified render target.
74372b7a4f565354d2101092c6bac6f9550ad506fdreed@google.com     */
756fcd1ef244f50b382627cdc7cdb50eb9e2dd46ebcommit-bot@chromium.org    static SkSurface* NewRenderTargetDirect(GrRenderTarget*,
766fcd1ef244f50b382627cdc7cdb50eb9e2dd46ebcommit-bot@chromium.org                                            TextRenderMode trm = kStandard_TextRenderMode);
771dab403e447f4f663690e018651338304fe6e86askia.committer@gmail.com
785d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com    /**
795d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com     *  Return a new surface whose contents will be drawn to an offscreen
805d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com     *  render target, allocated by the surface.
815d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com     */
826fcd1ef244f50b382627cdc7cdb50eb9e2dd46ebcommit-bot@chromium.org    static SkSurface* NewRenderTarget(GrContext*, const SkImageInfo&, int sampleCount = 0,
836fcd1ef244f50b382627cdc7cdb50eb9e2dd46ebcommit-bot@chromium.org                                      TextRenderMode trm = kStandard_TextRenderMode);
845d4ba8869476831ee73b15a052af8003d0a1fa2ereed@google.com
85d8a57af725e8fa8905207df3cf7465be50598752commit-bot@chromium.org    /**
86d8a57af725e8fa8905207df3cf7465be50598752commit-bot@chromium.org     *  Return a new surface whose contents will be drawn to an offscreen
87d8a57af725e8fa8905207df3cf7465be50598752commit-bot@chromium.org     *  render target, allocated by the surface from the scratch texture pool
88d8a57af725e8fa8905207df3cf7465be50598752commit-bot@chromium.org     *  managed by the GrContext. The scratch texture pool serves the purpose
89d8a57af725e8fa8905207df3cf7465be50598752commit-bot@chromium.org     *  of retaining textures after they are no longer in use in order to
90d8a57af725e8fa8905207df3cf7465be50598752commit-bot@chromium.org     *  re-use them later without having to re-allocate.  Scratch textures
91d8a57af725e8fa8905207df3cf7465be50598752commit-bot@chromium.org     *  should be used in cases where high turnover is expected. This allows,
92d8a57af725e8fa8905207df3cf7465be50598752commit-bot@chromium.org     *  for example, the copy on write to recycle a texture from a recently
93d8a57af725e8fa8905207df3cf7465be50598752commit-bot@chromium.org     *  released SkImage snapshot of the surface.
94d8a57af725e8fa8905207df3cf7465be50598752commit-bot@chromium.org     *  Note: Scratch textures count against the GrContext's cached resource
95d8a57af725e8fa8905207df3cf7465be50598752commit-bot@chromium.org     *  budget.
96d8a57af725e8fa8905207df3cf7465be50598752commit-bot@chromium.org     */
976fcd1ef244f50b382627cdc7cdb50eb9e2dd46ebcommit-bot@chromium.org    static SkSurface* NewScratchRenderTarget(GrContext*, const SkImageInfo&, int sampleCount = 0,
986fcd1ef244f50b382627cdc7cdb50eb9e2dd46ebcommit-bot@chromium.org                                             TextRenderMode trm = kStandard_TextRenderMode);
99d8a57af725e8fa8905207df3cf7465be50598752commit-bot@chromium.org
100889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com    int width() const { return fWidth; }
101889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com    int height() const { return fHeight; }
102889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com
103889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com    /**
104889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com     *  Returns a unique non-zero, unique value identifying the content of this
105889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com     *  surface. Each time the content is changed changed, either by drawing
106889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com     *  into this surface, or explicitly calling notifyContentChanged()) this
107889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com     *  method will return a new value.
108889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com     *
109889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com     *  If this surface is empty (i.e. has a zero-dimention), this will return
110889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com     *  0.
111889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com     */
11297af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com    uint32_t generationID();
113fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
114889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com    /**
115c4c9870953037be94da00ac9db887d171f6e479ccommit-bot@chromium.org     *  Modes that can be passed to notifyContentWillChange
116c4c9870953037be94da00ac9db887d171f6e479ccommit-bot@chromium.org     */
117c4c9870953037be94da00ac9db887d171f6e479ccommit-bot@chromium.org    enum ContentChangeMode {
118e36a168d132a70d04eb696d8b50e2aea5c725bffskia.committer@gmail.com        /**
119c4c9870953037be94da00ac9db887d171f6e479ccommit-bot@chromium.org         *  Use this mode if it is known that the upcoming content changes will
120c4c9870953037be94da00ac9db887d171f6e479ccommit-bot@chromium.org         *  clear or overwrite prior contents, thus making them discardable.
121c4c9870953037be94da00ac9db887d171f6e479ccommit-bot@chromium.org         */
122c4c9870953037be94da00ac9db887d171f6e479ccommit-bot@chromium.org        kDiscard_ContentChangeMode,
123e36a168d132a70d04eb696d8b50e2aea5c725bffskia.committer@gmail.com        /**
124c4c9870953037be94da00ac9db887d171f6e479ccommit-bot@chromium.org         *  Use this mode if prior surface contents need to be preserved or
125c4c9870953037be94da00ac9db887d171f6e479ccommit-bot@chromium.org         *  if in doubt.
126c4c9870953037be94da00ac9db887d171f6e479ccommit-bot@chromium.org         */
127c4c9870953037be94da00ac9db887d171f6e479ccommit-bot@chromium.org        kRetain_ContentChangeMode,
128c4c9870953037be94da00ac9db887d171f6e479ccommit-bot@chromium.org    };
129c4c9870953037be94da00ac9db887d171f6e479ccommit-bot@chromium.org
130c4c9870953037be94da00ac9db887d171f6e479ccommit-bot@chromium.org    /**
131c4c9870953037be94da00ac9db887d171f6e479ccommit-bot@chromium.org     *  Call this if the contents are about to change. This will (lazily) force a new
132889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com     *  value to be returned from generationID() when it is called next.
133889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com     */
134c4c9870953037be94da00ac9db887d171f6e479ccommit-bot@chromium.org    void notifyContentWillChange(ContentChangeMode mode);
135fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
136889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com    /**
1379ea5a3bc7361cb88d37280b5922fba9430fed328reed@google.com     *  Return a canvas that will draw into this surface. This will always
1389ea5a3bc7361cb88d37280b5922fba9430fed328reed@google.com     *  return the same canvas for a given surface, and is manged/owned by the
1399ea5a3bc7361cb88d37280b5922fba9430fed328reed@google.com     *  surface. It should not be used when its parent surface has gone out of
1409ea5a3bc7361cb88d37280b5922fba9430fed328reed@google.com     *  scope.
141889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com     */
1429ea5a3bc7361cb88d37280b5922fba9430fed328reed@google.com    SkCanvas* getCanvas();
143889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com
144889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com    /**
145889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com     *  Return a new surface that is "compatible" with this one, in that it will
146889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com     *  efficiently be able to be drawn into this surface. Typical calling
147889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com     *  pattern:
148889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com     *
149889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com     *  SkSurface* A = SkSurface::New...();
150889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com     *  SkCanvas* canvasA = surfaceA->newCanvas();
151889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com     *  ...
152889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com     *  SkSurface* surfaceB = surfaceA->newSurface(...);
153889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com     *  SkCanvas* canvasB = surfaceB->newCanvas();
154889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com     *  ... // draw using canvasB
155889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com     *  canvasA->drawSurface(surfaceB); // <--- this will always be optimal!
156889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com     */
1572bd8b8100529c96c81c30f749f672f4caf775b04reed@google.com    SkSurface* newSurface(const SkImageInfo&);
158889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com
159889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com    /**
160889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com     *  Returns an image of the current state of the surface pixels up to this
161889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com     *  point. Subsequent changes to the surface (by drawing into its canvas)
162889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com     *  will not be reflected in this image.
163889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com     */
1645ee449af7448c202cfc6e9a359d8f996392885b2junov@chromium.org    SkImage* newImageSnapshot();
165889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com
166889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com    /**
167889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com     *  Thought the caller could get a snapshot image explicitly, and draw that,
168889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com     *  it seems that directly drawing a surface into another canvas might be
169889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com     *  a common pattern, and that we could possibly be more efficient, since
170889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com     *  we'd know that the "snapshot" need only live until we've handed it off
171889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com     *  to the canvas.
172889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com     */
173889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com    void draw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*);
174889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com
175c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org    /**
176c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org     *  If the surface has direct access to its pixels (i.e. they are in local
177c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org     *  RAM) return the const-address of those pixels, and if not null, return
178c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org     *  the ImageInfo and rowBytes. The returned address is only valid while
179c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org     *  the surface object is in scope, and no API call is made on the surface
180c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org     *  or its canvas.
181c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org     *
182c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org     *  On failure, returns NULL and the info and rowBytes parameters are
183c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org     *  ignored.
184c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org     */
185c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org    const void* peekPixels(SkImageInfo* info, size_t* rowBytes);
186c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org
187889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.comprotected:
188889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com    SkSurface(int width, int height);
1891360c52b10dad45d7a6850370eab40c6253d7988reed@google.com    SkSurface(const SkImageInfo&);
190889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com
19197af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com    // called by subclass if their contents have changed
19297af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com    void dirtyGenerationID() {
19397af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com        fGenerationID = 0;
19497af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com    }
19597af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com
196889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.comprivate:
19797af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com    const int   fWidth;
19897af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com    const int   fHeight;
19997af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com    uint32_t    fGenerationID;
200a27096b4740775ae141fd0abaf456d706065c5eeskia.committer@gmail.com
2017edfb4939eb1fa642d4cc24d559c711555728259reed@google.com    typedef SkRefCnt INHERITED;
202889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com};
203889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com
204889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com#endif
205