Home | History | Annotate | Download | only in pipe
      1 /*
      2  * Copyright 2011 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 
      9 
     10 #ifndef SkGPipe_DEFINED
     11 #define SkGPipe_DEFINED
     12 
     13 #include "SkFlattenable.h"
     14 #include "SkPicture.h"
     15 #include "SkWriter32.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 
     44     /**
     45      *  Set a function for decoding bitmaps that have encoded data.
     46      */
     47     void setBitmapDecoder(SkPicture::InstallPixelRefProc proc) { fProc = proc; }
     48 
     49     // data must be 4-byte aligned
     50     // length must be a multiple of 4
     51     Status playback(const void* data, size_t length, uint32_t playbackFlags = 0,
     52                     size_t* bytesRead = NULL);
     53 private:
     54     SkCanvas*                       fCanvas;
     55     class SkGPipeState*             fState;
     56     SkPicture::InstallPixelRefProc  fProc;
     57 };
     58 
     59 ///////////////////////////////////////////////////////////////////////////////
     60 
     61 class SkGPipeCanvas;
     62 
     63 class SkGPipeController {
     64 public:
     65     SkGPipeController() : fCanvas(NULL) {}
     66     virtual ~SkGPipeController();
     67 
     68     /**
     69      *  Called periodically by the writer, to get a working buffer of RAM to
     70      *  write into. The actual size of the block is also returned, and must be
     71      *  actual >= minRequest. If NULL is returned, then actual is ignored and
     72      *  writing will stop.
     73      *
     74      *  The returned block must be 4-byte aligned, and actual must be a
     75      *  multiple of 4.
     76      *  minRequest will always be a multiple of 4.
     77      */
     78     virtual void* requestBlock(size_t minRequest, size_t* actual) = 0;
     79 
     80     /**
     81      *  This is called each time some atomic portion of the data has been
     82      *  written to the block (most recently returned by requestBlock()).
     83      *  If bytes == 0, then the writer has finished.
     84      *
     85      *  bytes will always be a multiple of 4.
     86      */
     87     virtual void notifyWritten(size_t bytes) = 0;
     88     virtual int numberOfReaders() const { return 1; }
     89 
     90 private:
     91     friend class SkGPipeWriter;
     92     void setCanvas(SkGPipeCanvas*);
     93 
     94     SkGPipeCanvas* fCanvas;
     95 };
     96 
     97 class SkGPipeWriter {
     98 public:
     99     SkGPipeWriter();
    100     ~SkGPipeWriter();
    101 
    102     bool isRecording() const { return NULL != fCanvas; }
    103 
    104     enum Flags {
    105         /**
    106          *  Tells the writer that the reader will be in a different process, so
    107          *  (for example) we cannot put function pointers in the stream.
    108          */
    109         kCrossProcess_Flag              = 1 << 0,
    110 
    111         /**
    112          *  Only meaningful if kCrossProcess_Flag is set. Tells the writer that
    113          *  in spite of being cross process, it will have shared address space
    114          *  with the reader, so the two can share large objects (like SkBitmaps).
    115          */
    116         kSharedAddressSpace_Flag        = 1 << 1,
    117 
    118         /**
    119          *  Tells the writer that there will be multiple threads reading the stream
    120          *  simultaneously.
    121          */
    122         kSimultaneousReaders_Flag       = 1 << 2,
    123     };
    124 
    125     SkCanvas* startRecording(SkGPipeController*, uint32_t flags = 0,
    126         uint32_t width = kDefaultRecordingCanvasSize,
    127         uint32_t height = kDefaultRecordingCanvasSize);
    128 
    129     // called in destructor, but can be called sooner once you know there
    130     // should be no more drawing calls made into the recording canvas.
    131     void endRecording();
    132 
    133     /**
    134      *  Tells the writer to commit all recorded draw commands to the
    135      *  controller immediately.
    136      *  @param detachCurrentBlock Set to true to request that the next draw
    137      *      command be recorded in a new block.
    138      */
    139     void flushRecording(bool detachCurrentBlock);
    140 
    141     /**
    142      * Return the amount of bytes being used for recording. Note that this
    143      * does not include the amount of storage written to the stream, which is
    144      * controlled by the SkGPipeController.
    145      * Currently only returns the amount used for SkBitmaps, since they are
    146      * potentially unbounded (if the client is not calling playback).
    147      */
    148     size_t storageAllocatedForRecording() const;
    149 
    150     /**
    151      * Attempt to reduce the storage allocated for recording by evicting
    152      * cache resources.
    153      * @param bytesToFree minimum number of bytes that should be attempted to
    154      *   be freed.
    155      * @return number of bytes actually freed.
    156      */
    157     size_t freeMemoryIfPossible(size_t bytesToFree);
    158 
    159 private:
    160     enum {
    161         kDefaultRecordingCanvasSize = 32767,
    162     };
    163 
    164     SkGPipeCanvas* fCanvas;
    165     SkWriter32     fWriter;
    166 };
    167 
    168 #endif
    169