180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/*
280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2011 Google Inc.
380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *
480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be
580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file.
680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifndef SkGPipe_DEFINED
1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SkGPipe_DEFINED
1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkFlattenable.h"
147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "SkPicture.h"
157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "SkWriter32.h"
1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruclass SkCanvas;
1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// XLib.h might have defined Status already (ugh)
2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef Status
2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    #undef Status
2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruclass SkGPipeReader {
2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupublic:
2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkGPipeReader();
2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkGPipeReader(SkCanvas* target);
2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    ~SkGPipeReader();
2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    enum Status {
3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        kDone_Status,   //!< no more data expected from reader
3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        kEOF_Status,    //!< need more data from reader
3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        kError_Status,  //!< encountered error
3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        kReadAtom_Status//!< finished reading an atom
3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    };
3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    enum PlaybackFlags {
3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        kReadAtom_PlaybackFlag = 0x1, //!< playback a single command from the stream
3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        kSilent_PlaybackFlag   = 0x2, //!< playback without drawing
4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    };
4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void setCanvas(SkCanvas*);
437839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
447839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    /**
457839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger     *  Set a function for decoding bitmaps that have encoded data.
467839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger     */
477839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    void setBitmapDecoder(SkPicture::InstallPixelRefProc proc) { fProc = proc; }
487839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // data must be 4-byte aligned
5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // length must be a multiple of 4
5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    Status playback(const void* data, size_t length, uint32_t playbackFlags = 0,
5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    size_t* bytesRead = NULL);
5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprivate:
547839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkCanvas*                       fCanvas;
557839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    class SkGPipeState*             fState;
567839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkPicture::InstallPixelRefProc  fProc;
5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru};
5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru///////////////////////////////////////////////////////////////////////////////
6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruclass SkGPipeCanvas;
6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruclass SkGPipeController {
6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupublic:
6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkGPipeController() : fCanvas(NULL) {}
6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    virtual ~SkGPipeController();
6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /**
6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *  Called periodically by the writer, to get a working buffer of RAM to
7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *  write into. The actual size of the block is also returned, and must be
7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *  actual >= minRequest. If NULL is returned, then actual is ignored and
7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *  writing will stop.
7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *
7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *  The returned block must be 4-byte aligned, and actual must be a
7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *  multiple of 4.
7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *  minRequest will always be a multiple of 4.
7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     */
7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    virtual void* requestBlock(size_t minRequest, size_t* actual) = 0;
7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /**
8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *  This is called each time some atomic portion of the data has been
8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *  written to the block (most recently returned by requestBlock()).
8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *  If bytes == 0, then the writer has finished.
8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *
8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *  bytes will always be a multiple of 4.
8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     */
8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    virtual void notifyWritten(size_t bytes) = 0;
8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    virtual int numberOfReaders() const { return 1; }
8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprivate:
9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    friend class SkGPipeWriter;
9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void setCanvas(SkGPipeCanvas*);
9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
9480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkGPipeCanvas* fCanvas;
9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru};
9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruclass SkGPipeWriter {
9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupublic:
9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkGPipeWriter();
10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    ~SkGPipeWriter();
10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bool isRecording() const { return NULL != fCanvas; }
10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    enum Flags {
10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        /**
10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru         *  Tells the writer that the reader will be in a different process, so
10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru         *  (for example) we cannot put function pointers in the stream.
10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru         */
10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        kCrossProcess_Flag              = 1 << 0,
11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
11180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        /**
11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru         *  Only meaningful if kCrossProcess_Flag is set. Tells the writer that
11380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru         *  in spite of being cross process, it will have shared address space
11480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru         *  with the reader, so the two can share large objects (like SkBitmaps).
11580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru         */
11680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        kSharedAddressSpace_Flag        = 1 << 1,
11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        /**
11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru         *  Tells the writer that there will be multiple threads reading the stream
12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru         *  simultaneously.
12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru         */
12280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        kSimultaneousReaders_Flag       = 1 << 2,
12380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    };
12480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
12580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkCanvas* startRecording(SkGPipeController*, uint32_t flags = 0,
12680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        uint32_t width = kDefaultRecordingCanvasSize,
12780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        uint32_t height = kDefaultRecordingCanvasSize);
12880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
12980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // called in destructor, but can be called sooner once you know there
13080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // should be no more drawing calls made into the recording canvas.
13180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void endRecording();
13280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
13380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /**
13480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *  Tells the writer to commit all recorded draw commands to the
13580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *  controller immediately.
13680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *  @param detachCurrentBlock Set to true to request that the next draw
13780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *      command be recorded in a new block.
13880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     */
13980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void flushRecording(bool detachCurrentBlock);
14080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
14180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /**
14280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     * Return the amount of bytes being used for recording. Note that this
14380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     * does not include the amount of storage written to the stream, which is
14480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     * controlled by the SkGPipeController.
14580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     * Currently only returns the amount used for SkBitmaps, since they are
14680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     * potentially unbounded (if the client is not calling playback).
14780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     */
14880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    size_t storageAllocatedForRecording() const;
14980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
15080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /**
15180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     * Attempt to reduce the storage allocated for recording by evicting
15280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     * cache resources.
15380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     * @param bytesToFree minimum number of bytes that should be attempted to
15480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *   be freed.
15580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     * @return number of bytes actually freed.
15680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     */
15780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    size_t freeMemoryIfPossible(size_t bytesToFree);
15880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
15980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprivate:
16080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    enum {
16180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        kDefaultRecordingCanvasSize = 32767,
16280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    };
16380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
16480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkGPipeCanvas* fCanvas;
16580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkWriter32     fWriter;
16680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru};
16780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
16880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
169