1 /* 2 * Copyright 2014 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 SkPictureRecorder_DEFINED 9 #define SkPictureRecorder_DEFINED 10 11 #include "../private/SkMiniRecorder.h" 12 #include "SkBBHFactory.h" 13 #include "SkPicture.h" 14 #include "SkRefCnt.h" 15 16 #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK 17 namespace android { 18 class Picture; 19 }; 20 #endif 21 22 class SkCanvas; 23 class SkDrawable; 24 class SkPictureRecord; 25 class SkRecord; 26 class SkRecorder; 27 28 class SK_API SkPictureRecorder : SkNoncopyable { 29 public: 30 SkPictureRecorder(); 31 ~SkPictureRecorder(); 32 33 enum RecordFlags { 34 // This flag indicates that, if some BHH is being computed, saveLayer 35 // information should also be extracted at the same time. 36 kComputeSaveLayerInfo_RecordFlag = 0x01, 37 38 // If you call drawPicture() or drawDrawable() on the recording canvas, this flag forces 39 // that object to playback its contents immediately rather than reffing the object. 40 kPlaybackDrawPicture_RecordFlag = 0x02, 41 }; 42 43 /** Returns the canvas that records the drawing commands. 44 @param bounds the cull rect used when recording this picture. Any drawing the falls outside 45 of this rect is undefined, and may be drawn or it may not. 46 @param bbhFactory factory to create desired acceleration structure 47 @param recordFlags optional flags that control recording. 48 @return the canvas. 49 */ 50 SkCanvas* beginRecording(const SkRect& bounds, 51 SkBBHFactory* bbhFactory = NULL, 52 uint32_t recordFlags = 0); 53 54 SkCanvas* beginRecording(SkScalar width, SkScalar height, 55 SkBBHFactory* bbhFactory = NULL, 56 uint32_t recordFlags = 0) { 57 return this->beginRecording(SkRect::MakeWH(width, height), bbhFactory, recordFlags); 58 } 59 60 /** Returns the recording canvas if one is active, or NULL if recording is 61 not active. This does not alter the refcnt on the canvas (if present). 62 */ 63 SkCanvas* getRecordingCanvas(); 64 65 /** 66 * Signal that the caller is done recording. This invalidates the canvas returned by 67 * beginRecording/getRecordingCanvas. Ownership of the object is passed to the caller, who 68 * must call unref() when they are done using it. 69 * 70 * The returned picture is immutable. If during recording drawables were added to the canvas, 71 * these will have been "drawn" into a recording canvas, so that this resulting picture will 72 * reflect their current state, but will not contain a live reference to the drawables 73 * themselves. 74 */ 75 SkPicture* SK_WARN_UNUSED_RESULT endRecordingAsPicture(); 76 77 /** 78 * Signal that the caller is done recording, and update the cull rect to use for bounding 79 * box hierarchy (BBH) generation. The behavior is the same as calling 80 * endRecordingAsPicture(), except that this method updates the cull rect initially passed 81 * into beginRecording. 82 * @param cullRect the new culling rectangle to use as the overall bound for BBH generation 83 * and subsequent culling operations. 84 * @return the picture containing the recorded content. 85 */ 86 SkPicture* SK_WARN_UNUSED_RESULT endRecordingAsPicture(const SkRect& cullRect); 87 88 /** 89 * Signal that the caller is done recording. This invalidates the canvas returned by 90 * beginRecording/getRecordingCanvas. Ownership of the object is passed to the caller, who 91 * must call unref() when they are done using it. 92 * 93 * Unlike endRecordingAsPicture(), which returns an immutable picture, the returned drawable 94 * may contain live references to other drawables (if they were added to the recording canvas) 95 * and therefore this drawable will reflect the current state of those nested drawables anytime 96 * it is drawn or a new picture is snapped from it (by calling drawable->newPictureSnapshot()). 97 */ 98 SkDrawable* SK_WARN_UNUSED_RESULT endRecordingAsDrawable(); 99 100 // Legacy API -- use endRecordingAsPicture instead. endRecording()101 SkPicture* SK_WARN_UNUSED_RESULT endRecording() { return this->endRecordingAsPicture(); } 102 103 private: 104 void reset(); 105 106 /** Replay the current (partially recorded) operation stream into 107 canvas. This call doesn't close the current recording. 108 */ 109 #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK 110 friend class android::Picture; 111 #endif 112 friend class SkPictureRecorderReplayTester; // for unit testing 113 void partialReplay(SkCanvas* canvas) const; 114 115 bool fActivelyRecording; 116 uint32_t fFlags; 117 SkRect fCullRect; 118 SkAutoTUnref<SkBBoxHierarchy> fBBH; 119 SkAutoTUnref<SkRecorder> fRecorder; 120 SkAutoTUnref<SkRecord> fRecord; 121 SkMiniRecorder fMiniRecorder; 122 123 typedef SkNoncopyable INHERITED; 124 }; 125 126 #endif 127