15bb6825f10d64834ad1d1d967f590aebae285360epoger@google.com/* 25bb6825f10d64834ad1d1d967f590aebae285360epoger@google.com * Copyright 2011 Google Inc. 35bb6825f10d64834ad1d1d967f590aebae285360epoger@google.com * 45bb6825f10d64834ad1d1d967f590aebae285360epoger@google.com * Use of this source code is governed by a BSD-style license that can be 55bb6825f10d64834ad1d1d967f590aebae285360epoger@google.com * found in the LICENSE file. 6d873bc41331cc176b7368fa73ca9dcff01c08a2freed@google.com */ 7d873bc41331cc176b7368fa73ca9dcff01c08a2freed@google.com 8d873bc41331cc176b7368fa73ca9dcff01c08a2freed@google.com 95bb6825f10d64834ad1d1d967f590aebae285360epoger@google.com 10d873bc41331cc176b7368fa73ca9dcff01c08a2freed@google.com#ifndef SkGPipe_DEFINED 11d873bc41331cc176b7368fa73ca9dcff01c08a2freed@google.com#define SkGPipe_DEFINED 12d873bc41331cc176b7368fa73ca9dcff01c08a2freed@google.com 13fe6d81c22e1f4ceeb67e2b857674eb38bda8ffd8reed@google.com#include "SkFlattenable.h" 14da4fa6fab2822f08ef9f68917de6dd6dc3a883d7scroggo@google.com#include "SkPicture.h" 15da4fa6fab2822f08ef9f68917de6dd6dc3a883d7scroggo@google.com#include "SkWriter32.h" 16d873bc41331cc176b7368fa73ca9dcff01c08a2freed@google.com 17d873bc41331cc176b7368fa73ca9dcff01c08a2freed@google.comclass SkCanvas; 18d873bc41331cc176b7368fa73ca9dcff01c08a2freed@google.com 199343fc93e5c18d7632ad2aaceb8aeb59dc8d2cfcreed@google.com// XLib.h might have defined Status already (ugh) 209343fc93e5c18d7632ad2aaceb8aeb59dc8d2cfcreed@google.com#ifdef Status 219343fc93e5c18d7632ad2aaceb8aeb59dc8d2cfcreed@google.com #undef Status 229343fc93e5c18d7632ad2aaceb8aeb59dc8d2cfcreed@google.com#endif 239343fc93e5c18d7632ad2aaceb8aeb59dc8d2cfcreed@google.com 24d873bc41331cc176b7368fa73ca9dcff01c08a2freed@google.comclass SkGPipeReader { 25d873bc41331cc176b7368fa73ca9dcff01c08a2freed@google.compublic: 26c55e5aad7046475cfe53c0e68ef89ae31c605ad4scroggo@google.com SkGPipeReader(); 27d873bc41331cc176b7368fa73ca9dcff01c08a2freed@google.com SkGPipeReader(SkCanvas* target); 28d873bc41331cc176b7368fa73ca9dcff01c08a2freed@google.com ~SkGPipeReader(); 29d873bc41331cc176b7368fa73ca9dcff01c08a2freed@google.com 30d873bc41331cc176b7368fa73ca9dcff01c08a2freed@google.com enum Status { 31d873bc41331cc176b7368fa73ca9dcff01c08a2freed@google.com kDone_Status, //!< no more data expected from reader 32d873bc41331cc176b7368fa73ca9dcff01c08a2freed@google.com kEOF_Status, //!< need more data from reader 339cc4baf1dec7c7f6b34f0db037a004e97d7e4201yangsu@google.com kError_Status, //!< encountered error 349cc4baf1dec7c7f6b34f0db037a004e97d7e4201yangsu@google.com kReadAtom_Status//!< finished reading an atom 35d873bc41331cc176b7368fa73ca9dcff01c08a2freed@google.com }; 36d873bc41331cc176b7368fa73ca9dcff01c08a2freed@google.com 377c6664b9c8b7046cf68a5f86cc6d9809b244bd71junov@chromium.org enum PlaybackFlags { 387c6664b9c8b7046cf68a5f86cc6d9809b244bd71junov@chromium.org kReadAtom_PlaybackFlag = 0x1, //!< playback a single command from the stream 397c6664b9c8b7046cf68a5f86cc6d9809b244bd71junov@chromium.org kSilent_PlaybackFlag = 0x2, //!< playback without drawing 407c6664b9c8b7046cf68a5f86cc6d9809b244bd71junov@chromium.org }; 417c6664b9c8b7046cf68a5f86cc6d9809b244bd71junov@chromium.org 42c55e5aad7046475cfe53c0e68ef89ae31c605ad4scroggo@google.com void setCanvas(SkCanvas*); 43da4fa6fab2822f08ef9f68917de6dd6dc3a883d7scroggo@google.com 44da4fa6fab2822f08ef9f68917de6dd6dc3a883d7scroggo@google.com /** 45da4fa6fab2822f08ef9f68917de6dd6dc3a883d7scroggo@google.com * Set a function for decoding bitmaps that have encoded data. 46da4fa6fab2822f08ef9f68917de6dd6dc3a883d7scroggo@google.com */ 47da4fa6fab2822f08ef9f68917de6dd6dc3a883d7scroggo@google.com void setBitmapDecoder(SkPicture::InstallPixelRefProc proc) { fProc = proc; } 48da4fa6fab2822f08ef9f68917de6dd6dc3a883d7scroggo@google.com 49dfd8f38cfabda080d4aefbf8de7dfc8617aae8cdreed@google.com // data must be 4-byte aligned 50dfd8f38cfabda080d4aefbf8de7dfc8617aae8cdreed@google.com // length must be a multiple of 4 517c6664b9c8b7046cf68a5f86cc6d9809b244bd71junov@chromium.org Status playback(const void* data, size_t length, uint32_t playbackFlags = 0, 527c6664b9c8b7046cf68a5f86cc6d9809b244bd71junov@chromium.org size_t* bytesRead = NULL); 53d873bc41331cc176b7368fa73ca9dcff01c08a2freed@google.comprivate: 54da4fa6fab2822f08ef9f68917de6dd6dc3a883d7scroggo@google.com SkCanvas* fCanvas; 55da4fa6fab2822f08ef9f68917de6dd6dc3a883d7scroggo@google.com class SkGPipeState* fState; 56da4fa6fab2822f08ef9f68917de6dd6dc3a883d7scroggo@google.com SkPicture::InstallPixelRefProc fProc; 57d873bc41331cc176b7368fa73ca9dcff01c08a2freed@google.com}; 58d873bc41331cc176b7368fa73ca9dcff01c08a2freed@google.com 59d873bc41331cc176b7368fa73ca9dcff01c08a2freed@google.com/////////////////////////////////////////////////////////////////////////////// 60d873bc41331cc176b7368fa73ca9dcff01c08a2freed@google.com 612e37e2b709e0d38ad3689ee4e520f2f3b3bad9a3scroggo@google.comclass SkGPipeCanvas; 622e37e2b709e0d38ad3689ee4e520f2f3b3bad9a3scroggo@google.com 63dfd8f38cfabda080d4aefbf8de7dfc8617aae8cdreed@google.comclass SkGPipeController { 64c16a7b69f767d8a1608964eaea352d27fcf4658dreed@google.compublic: 652e37e2b709e0d38ad3689ee4e520f2f3b3bad9a3scroggo@google.com SkGPipeController() : fCanvas(NULL) {} 662e37e2b709e0d38ad3689ee4e520f2f3b3bad9a3scroggo@google.com virtual ~SkGPipeController(); 672e37e2b709e0d38ad3689ee4e520f2f3b3bad9a3scroggo@google.com 68c16a7b69f767d8a1608964eaea352d27fcf4658dreed@google.com /** 69dfd8f38cfabda080d4aefbf8de7dfc8617aae8cdreed@google.com * Called periodically by the writer, to get a working buffer of RAM to 70dfd8f38cfabda080d4aefbf8de7dfc8617aae8cdreed@google.com * write into. The actual size of the block is also returned, and must be 71dfd8f38cfabda080d4aefbf8de7dfc8617aae8cdreed@google.com * actual >= minRequest. If NULL is returned, then actual is ignored and 72dfd8f38cfabda080d4aefbf8de7dfc8617aae8cdreed@google.com * writing will stop. 73c16a7b69f767d8a1608964eaea352d27fcf4658dreed@google.com * 74dfd8f38cfabda080d4aefbf8de7dfc8617aae8cdreed@google.com * The returned block must be 4-byte aligned, and actual must be a 75dfd8f38cfabda080d4aefbf8de7dfc8617aae8cdreed@google.com * multiple of 4. 76dfd8f38cfabda080d4aefbf8de7dfc8617aae8cdreed@google.com * minRequest will always be a multiple of 4. 77dfd8f38cfabda080d4aefbf8de7dfc8617aae8cdreed@google.com */ 78dfd8f38cfabda080d4aefbf8de7dfc8617aae8cdreed@google.com virtual void* requestBlock(size_t minRequest, size_t* actual) = 0; 79dfd8f38cfabda080d4aefbf8de7dfc8617aae8cdreed@google.com 80dfd8f38cfabda080d4aefbf8de7dfc8617aae8cdreed@google.com /** 81dfd8f38cfabda080d4aefbf8de7dfc8617aae8cdreed@google.com * This is called each time some atomic portion of the data has been 82dfd8f38cfabda080d4aefbf8de7dfc8617aae8cdreed@google.com * written to the block (most recently returned by requestBlock()). 83dfd8f38cfabda080d4aefbf8de7dfc8617aae8cdreed@google.com * If bytes == 0, then the writer has finished. 84c16a7b69f767d8a1608964eaea352d27fcf4658dreed@google.com * 85dfd8f38cfabda080d4aefbf8de7dfc8617aae8cdreed@google.com * bytes will always be a multiple of 4. 86c16a7b69f767d8a1608964eaea352d27fcf4658dreed@google.com */ 87dfd8f38cfabda080d4aefbf8de7dfc8617aae8cdreed@google.com virtual void notifyWritten(size_t bytes) = 0; 883d87332c5f217ab77b5afdea98e0c592d3ed7177scroggo@google.com virtual int numberOfReaders() const { return 1; } 892e37e2b709e0d38ad3689ee4e520f2f3b3bad9a3scroggo@google.com 902e37e2b709e0d38ad3689ee4e520f2f3b3bad9a3scroggo@google.comprivate: 912e37e2b709e0d38ad3689ee4e520f2f3b3bad9a3scroggo@google.com friend class SkGPipeWriter; 922e37e2b709e0d38ad3689ee4e520f2f3b3bad9a3scroggo@google.com void setCanvas(SkGPipeCanvas*); 932e37e2b709e0d38ad3689ee4e520f2f3b3bad9a3scroggo@google.com 942e37e2b709e0d38ad3689ee4e520f2f3b3bad9a3scroggo@google.com SkGPipeCanvas* fCanvas; 95c16a7b69f767d8a1608964eaea352d27fcf4658dreed@google.com}; 96c16a7b69f767d8a1608964eaea352d27fcf4658dreed@google.com 97d873bc41331cc176b7368fa73ca9dcff01c08a2freed@google.comclass SkGPipeWriter { 98d873bc41331cc176b7368fa73ca9dcff01c08a2freed@google.compublic: 99d873bc41331cc176b7368fa73ca9dcff01c08a2freed@google.com SkGPipeWriter(); 100d873bc41331cc176b7368fa73ca9dcff01c08a2freed@google.com ~SkGPipeWriter(); 101d873bc41331cc176b7368fa73ca9dcff01c08a2freed@google.com 102d873bc41331cc176b7368fa73ca9dcff01c08a2freed@google.com bool isRecording() const { return NULL != fCanvas; } 103fe6d81c22e1f4ceeb67e2b857674eb38bda8ffd8reed@google.com 104fe6d81c22e1f4ceeb67e2b857674eb38bda8ffd8reed@google.com enum Flags { 10521a56d70754e439a2e0e9901f832c03fa0c7f85ascroggo@google.com /** 10621a56d70754e439a2e0e9901f832c03fa0c7f85ascroggo@google.com * Tells the writer that the reader will be in a different process, so 10721a56d70754e439a2e0e9901f832c03fa0c7f85ascroggo@google.com * (for example) we cannot put function pointers in the stream. 10821a56d70754e439a2e0e9901f832c03fa0c7f85ascroggo@google.com */ 10921a56d70754e439a2e0e9901f832c03fa0c7f85ascroggo@google.com kCrossProcess_Flag = 1 << 0, 110ea155c4294f320f667cfa534109163729fbe9590scroggo@google.com 11121a56d70754e439a2e0e9901f832c03fa0c7f85ascroggo@google.com /** 11221a56d70754e439a2e0e9901f832c03fa0c7f85ascroggo@google.com * Only meaningful if kCrossProcess_Flag is set. Tells the writer that 11321a56d70754e439a2e0e9901f832c03fa0c7f85ascroggo@google.com * in spite of being cross process, it will have shared address space 114ea155c4294f320f667cfa534109163729fbe9590scroggo@google.com * with the reader, so the two can share large objects (like SkBitmaps). 115ea155c4294f320f667cfa534109163729fbe9590scroggo@google.com */ 116ea155c4294f320f667cfa534109163729fbe9590scroggo@google.com kSharedAddressSpace_Flag = 1 << 1, 117ea155c4294f320f667cfa534109163729fbe9590scroggo@google.com 118ea155c4294f320f667cfa534109163729fbe9590scroggo@google.com /** 119ea155c4294f320f667cfa534109163729fbe9590scroggo@google.com * Tells the writer that there will be multiple threads reading the stream 120ea155c4294f320f667cfa534109163729fbe9590scroggo@google.com * simultaneously. 12121a56d70754e439a2e0e9901f832c03fa0c7f85ascroggo@google.com */ 122ea155c4294f320f667cfa534109163729fbe9590scroggo@google.com kSimultaneousReaders_Flag = 1 << 2, 123fe6d81c22e1f4ceeb67e2b857674eb38bda8ffd8reed@google.com }; 124fe6d81c22e1f4ceeb67e2b857674eb38bda8ffd8reed@google.com 1253b406e7776668715fce278a806d84f8a55bcc53djunov@chromium.org SkCanvas* startRecording(SkGPipeController*, uint32_t flags = 0, 1263b406e7776668715fce278a806d84f8a55bcc53djunov@chromium.org uint32_t width = kDefaultRecordingCanvasSize, 1273b406e7776668715fce278a806d84f8a55bcc53djunov@chromium.org uint32_t height = kDefaultRecordingCanvasSize); 128d873bc41331cc176b7368fa73ca9dcff01c08a2freed@google.com 129dfd8f38cfabda080d4aefbf8de7dfc8617aae8cdreed@google.com // called in destructor, but can be called sooner once you know there 130dfd8f38cfabda080d4aefbf8de7dfc8617aae8cdreed@google.com // should be no more drawing calls made into the recording canvas. 131dfd8f38cfabda080d4aefbf8de7dfc8617aae8cdreed@google.com void endRecording(); 132d873bc41331cc176b7368fa73ca9dcff01c08a2freed@google.com 133e5e1e7d999711ca9a3a9303531a79464f3d87ce8junov@chromium.org /** 134e5e1e7d999711ca9a3a9303531a79464f3d87ce8junov@chromium.org * Tells the writer to commit all recorded draw commands to the 135e5e1e7d999711ca9a3a9303531a79464f3d87ce8junov@chromium.org * controller immediately. 136e5e1e7d999711ca9a3a9303531a79464f3d87ce8junov@chromium.org * @param detachCurrentBlock Set to true to request that the next draw 137e5e1e7d999711ca9a3a9303531a79464f3d87ce8junov@chromium.org * command be recorded in a new block. 138e5e1e7d999711ca9a3a9303531a79464f3d87ce8junov@chromium.org */ 139e5e1e7d999711ca9a3a9303531a79464f3d87ce8junov@chromium.org void flushRecording(bool detachCurrentBlock); 140e5e1e7d999711ca9a3a9303531a79464f3d87ce8junov@chromium.org 141556930849b8dc0146aa8ded30a5043a9114b3f2bscroggo@google.com /** 142556930849b8dc0146aa8ded30a5043a9114b3f2bscroggo@google.com * Return the amount of bytes being used for recording. Note that this 143556930849b8dc0146aa8ded30a5043a9114b3f2bscroggo@google.com * does not include the amount of storage written to the stream, which is 144556930849b8dc0146aa8ded30a5043a9114b3f2bscroggo@google.com * controlled by the SkGPipeController. 145556930849b8dc0146aa8ded30a5043a9114b3f2bscroggo@google.com * Currently only returns the amount used for SkBitmaps, since they are 146556930849b8dc0146aa8ded30a5043a9114b3f2bscroggo@google.com * potentially unbounded (if the client is not calling playback). 147556930849b8dc0146aa8ded30a5043a9114b3f2bscroggo@google.com */ 1486c331d1751bbba5311f12d8bb8071afac1d4c525junov@chromium.org size_t storageAllocatedForRecording() const; 1496c331d1751bbba5311f12d8bb8071afac1d4c525junov@chromium.org 1506c331d1751bbba5311f12d8bb8071afac1d4c525junov@chromium.org /** 1516c331d1751bbba5311f12d8bb8071afac1d4c525junov@chromium.org * Attempt to reduce the storage allocated for recording by evicting 1526c331d1751bbba5311f12d8bb8071afac1d4c525junov@chromium.org * cache resources. 1536c331d1751bbba5311f12d8bb8071afac1d4c525junov@chromium.org * @param bytesToFree minimum number of bytes that should be attempted to 1546c331d1751bbba5311f12d8bb8071afac1d4c525junov@chromium.org * be freed. 1556c331d1751bbba5311f12d8bb8071afac1d4c525junov@chromium.org * @return number of bytes actually freed. 1566c331d1751bbba5311f12d8bb8071afac1d4c525junov@chromium.org */ 1576c331d1751bbba5311f12d8bb8071afac1d4c525junov@chromium.org size_t freeMemoryIfPossible(size_t bytesToFree); 158556930849b8dc0146aa8ded30a5043a9114b3f2bscroggo@google.com 159d873bc41331cc176b7368fa73ca9dcff01c08a2freed@google.comprivate: 1603b406e7776668715fce278a806d84f8a55bcc53djunov@chromium.org enum { 1613b406e7776668715fce278a806d84f8a55bcc53djunov@chromium.org kDefaultRecordingCanvasSize = 32767, 1623b406e7776668715fce278a806d84f8a55bcc53djunov@chromium.org }; 1633b406e7776668715fce278a806d84f8a55bcc53djunov@chromium.org 1642e37e2b709e0d38ad3689ee4e520f2f3b3bad9a3scroggo@google.com SkGPipeCanvas* fCanvas; 1652e37e2b709e0d38ad3689ee4e520f2f3b3bad9a3scroggo@google.com SkWriter32 fWriter; 166d873bc41331cc176b7368fa73ca9dcff01c08a2freed@google.com}; 167d873bc41331cc176b7368fa73ca9dcff01c08a2freed@google.com 168d873bc41331cc176b7368fa73ca9dcff01c08a2freed@google.com#endif 169