1 2 /* 3 * Copyright 2011 Google Inc. 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 9 10 11 #ifndef SkGPipe_DEFINED 12 #define SkGPipe_DEFINED 13 14 #include "SkWriter32.h" 15 #include "SkFlattenable.h" 16 17 class SkCanvas; 18 19 // XLib.h might have defined Status already (ugh) 20 #ifdef Status 21 #undef Status 22 #endif 23 24 class SkGPipeReader { 25 public: 26 SkGPipeReader(); 27 SkGPipeReader(SkCanvas* target); 28 ~SkGPipeReader(); 29 30 enum Status { 31 kDone_Status, //!< no more data expected from reader 32 kEOF_Status, //!< need more data from reader 33 kError_Status, //!< encountered error 34 kReadAtom_Status//!< finished reading an atom 35 }; 36 37 enum PlaybackFlags { 38 kReadAtom_PlaybackFlag = 0x1, //!< playback a single command from the stream 39 kSilent_PlaybackFlag = 0x2, //!< playback without drawing 40 }; 41 42 void setCanvas(SkCanvas*); 43 // data must be 4-byte aligned 44 // length must be a multiple of 4 45 Status playback(const void* data, size_t length, uint32_t playbackFlags = 0, 46 size_t* bytesRead = NULL); 47 private: 48 SkCanvas* fCanvas; 49 class SkGPipeState* fState; 50 }; 51 52 /////////////////////////////////////////////////////////////////////////////// 53 54 class SkGPipeCanvas; 55 56 class SkGPipeController { 57 public: 58 SkGPipeController() : fCanvas(NULL) {} 59 virtual ~SkGPipeController(); 60 61 /** 62 * Called periodically by the writer, to get a working buffer of RAM to 63 * write into. The actual size of the block is also returned, and must be 64 * actual >= minRequest. If NULL is returned, then actual is ignored and 65 * writing will stop. 66 * 67 * The returned block must be 4-byte aligned, and actual must be a 68 * multiple of 4. 69 * minRequest will always be a multiple of 4. 70 */ 71 virtual void* requestBlock(size_t minRequest, size_t* actual) = 0; 72 73 /** 74 * This is called each time some atomic portion of the data has been 75 * written to the block (most recently returned by requestBlock()). 76 * If bytes == 0, then the writer has finished. 77 * 78 * bytes will always be a multiple of 4. 79 */ 80 virtual void notifyWritten(size_t bytes) = 0; 81 virtual int numberOfReaders() const { return 1; } 82 83 private: 84 friend class SkGPipeWriter; 85 void setCanvas(SkGPipeCanvas*); 86 87 SkGPipeCanvas* fCanvas; 88 }; 89 90 class SkGPipeWriter { 91 public: 92 SkGPipeWriter(); 93 ~SkGPipeWriter(); 94 95 bool isRecording() const { return NULL != fCanvas; } 96 97 enum Flags { 98 /** 99 * Tells the writer that the reader will be in a different process, so 100 * (for example) we cannot put function pointers in the stream. 101 */ 102 kCrossProcess_Flag = 1 << 0, 103 104 /** 105 * Only meaningful if kCrossProcess_Flag is set. Tells the writer that 106 * in spite of being cross process, it will have shared address space 107 * with the reader, so the two can share large objects (like SkBitmaps). 108 */ 109 kSharedAddressSpace_Flag = 1 << 1, 110 111 /** 112 * Tells the writer that there will be multiple threads reading the stream 113 * simultaneously. 114 */ 115 kSimultaneousReaders_Flag = 1 << 2, 116 }; 117 118 SkCanvas* startRecording(SkGPipeController*, uint32_t flags = 0, 119 uint32_t width = kDefaultRecordingCanvasSize, 120 uint32_t height = kDefaultRecordingCanvasSize); 121 122 // called in destructor, but can be called sooner once you know there 123 // should be no more drawing calls made into the recording canvas. 124 void endRecording(); 125 126 /** 127 * Tells the writer to commit all recorded draw commands to the 128 * controller immediately. 129 * @param detachCurrentBlock Set to true to request that the next draw 130 * command be recorded in a new block. 131 */ 132 void flushRecording(bool detachCurrentBlock); 133 134 /** 135 * Return the amount of bytes being used for recording. Note that this 136 * does not include the amount of storage written to the stream, which is 137 * controlled by the SkGPipeController. 138 * Currently only returns the amount used for SkBitmaps, since they are 139 * potentially unbounded (if the client is not calling playback). 140 */ 141 size_t storageAllocatedForRecording() const; 142 143 /** 144 * Attempt to reduce the storage allocated for recording by evicting 145 * cache resources. 146 * @param bytesToFree minimum number of bytes that should be attempted to 147 * be freed. 148 * @return number of bytes actually freed. 149 */ 150 size_t freeMemoryIfPossible(size_t bytesToFree); 151 152 private: 153 enum { 154 kDefaultRecordingCanvasSize = 32767, 155 }; 156 157 SkGPipeCanvas* fCanvas; 158 SkWriter32 fWriter; 159 }; 160 161 #endif 162