SkGPipeWrite.cpp revision d6176b0dcacb124539e0cfd051e6d93a9782f020
1bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc.
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
7bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com */
8bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
910dccde54a769b8d472bccf8c1993034b93ef58dscroggo@google.com#include "SkBitmapHeap.h"
10bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com#include "SkCanvas.h"
1110dccde54a769b8d472bccf8c1993034b93ef58dscroggo@google.com#include "SkColorFilter.h"
128a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com#include "SkData.h"
1310dccde54a769b8d472bccf8c1993034b93ef58dscroggo@google.com#include "SkDrawLooper.h"
14bb6793bd7751f7a4e48c942567cd6c5270661a2freed@google.com#include "SkDevice.h"
15acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com#include "SkGPipe.h"
16bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com#include "SkGPipePriv.h"
1716d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com#include "SkImageFilter.h"
1810dccde54a769b8d472bccf8c1993034b93ef58dscroggo@google.com#include "SkMaskFilter.h"
1910dccde54a769b8d472bccf8c1993034b93ef58dscroggo@google.com#include "SkOrderedWriteBuffer.h"
2010dccde54a769b8d472bccf8c1993034b93ef58dscroggo@google.com#include "SkPaint.h"
2110dccde54a769b8d472bccf8c1993034b93ef58dscroggo@google.com#include "SkPathEffect.h"
2210dccde54a769b8d472bccf8c1993034b93ef58dscroggo@google.com#include "SkPictureFlat.h"
2310dccde54a769b8d472bccf8c1993034b93ef58dscroggo@google.com#include "SkRasterizer.h"
2410dccde54a769b8d472bccf8c1993034b93ef58dscroggo@google.com#include "SkShader.h"
25f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com#include "SkStream.h"
26b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com#include "SkTSearch.h"
27f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com#include "SkTypeface.h"
28bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com#include "SkWriter32.h"
29b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com
300c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.comstatic bool isCrossProcess(uint32_t flags) {
310c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com    return SkToBool(flags & SkGPipeWriter::kCrossProcess_Flag);
320c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com}
330c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com
34b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.comstatic SkFlattenable* get_paintflat(const SkPaint& paint, unsigned paintFlat) {
35b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com    SkASSERT(paintFlat < kCount_PaintFlats);
36b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com    switch (paintFlat) {
37b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com        case kColorFilter_PaintFlat:    return paint.getColorFilter();
380faac1e8579088a39f38d02ff675f14d7deb608dreed@google.com        case kDrawLooper_PaintFlat:     return paint.getLooper();
39b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com        case kMaskFilter_PaintFlat:     return paint.getMaskFilter();
40b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com        case kPathEffect_PaintFlat:     return paint.getPathEffect();
41b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com        case kRasterizer_PaintFlat:     return paint.getRasterizer();
42b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com        case kShader_PaintFlat:         return paint.getShader();
4316d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com        case kImageFilter_PaintFlat:    return paint.getImageFilter();
44b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com        case kXfermode_PaintFlat:       return paint.getXfermode();
45b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com    }
460c00f21fee3f5cfa3aa7e5d46ff94cb8cf340451tomhudson@google.com    SkDEBUGFAIL("never gets here");
47b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com    return NULL;
48b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com}
49bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
50f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.comstatic size_t writeTypeface(SkWriter32* writer, SkTypeface* typeface) {
51f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com    SkASSERT(typeface);
52f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com    SkDynamicMemoryWStream stream;
53f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com    typeface->serialize(&stream);
54f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com    size_t size = stream.getOffset();
55f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com    if (writer) {
56f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com        writer->write32(size);
578a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com        SkAutoDataUnref data(stream.copyToData());
5859f46b81f8bdd1b524f5cc43bc27603f9604c71arobertphillips@google.com        writer->writePad(data->data(), size);
59f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com    }
605af9b2032b552516c9223d9fb22185b022b13c62scroggo@google.com    return 4 + SkAlign4(size);
61f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com}
62f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com
63bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com///////////////////////////////////////////////////////////////////////////////
64bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
654dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.comclass FlattenableHeap : public SkFlatController {
664dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.compublic:
67664fab1b3454faea01cbae2f1dc2777c5afb9998scroggo@google.com    FlattenableHeap(int numFlatsToKeep, SkNamedFactorySet* fset, bool isCrossProcess)
681554360a9511d996e1618d19c163c810ef3f128cscroggo@google.com    : fNumFlatsToKeep(numFlatsToKeep) {
69664fab1b3454faea01cbae2f1dc2777c5afb9998scroggo@google.com        SkASSERT((isCrossProcess && fset != NULL) || (!isCrossProcess && NULL == fset));
70664fab1b3454faea01cbae2f1dc2777c5afb9998scroggo@google.com        if (isCrossProcess) {
71664fab1b3454faea01cbae2f1dc2777c5afb9998scroggo@google.com            this->setNamedFactorySet(fset);
72664fab1b3454faea01cbae2f1dc2777c5afb9998scroggo@google.com            this->setWriteBufferFlags(SkFlattenableWriteBuffer::kCrossProcess_Flag);
73664fab1b3454faea01cbae2f1dc2777c5afb9998scroggo@google.com        }
740c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com    }
754dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com
764dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com    ~FlattenableHeap() {
774dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com        fPointers.freeAll();
784dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com    }
794dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com
804dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com    virtual void* allocThrow(size_t bytes) SK_OVERRIDE;
814dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com
824dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com    virtual void unalloc(void* ptr) SK_OVERRIDE;
834dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com
847ca24437c71af06fc06ab5f6f261b185882fa440scroggo@google.com    void setBitmapStorage(SkBitmapHeap* heap) {
857ca24437c71af06fc06ab5f6f261b185882fa440scroggo@google.com        this->setBitmapHeap(heap);
867ca24437c71af06fc06ab5f6f261b185882fa440scroggo@google.com    }
87d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
884dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com    const SkFlatData* flatToReplace() const;
894dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com
904dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com    // Mark an SkFlatData as one that should not be returned by flatToReplace.
914dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com    // Takes the result of SkFlatData::index() as its parameter.
924dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com    void markFlatForKeeping(int index) {
934dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com        *fFlatsThatMustBeKept.append() = index;
944dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com    }
954dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com
964dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com    void markAllFlatsSafeToDelete() {
974dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com        fFlatsThatMustBeKept.reset();
984dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com    }
994dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com
1004dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.comprivate:
1014dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com    // Keep track of the indices (i.e. the result of SkFlatData::index()) of
1024dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com    // flats that must be kept, since they are on the current paint.
1034dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com    SkTDArray<int>   fFlatsThatMustBeKept;
1044dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com    SkTDArray<void*> fPointers;
1054dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com    const int        fNumFlatsToKeep;
1064dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com};
1074dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com
1084dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.comvoid FlattenableHeap::unalloc(void* ptr) {
1094dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com    int indexToRemove = fPointers.rfind(ptr);
1104dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com    if (indexToRemove >= 0) {
1114dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com        sk_free(ptr);
1124dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com        fPointers.remove(indexToRemove);
1134dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com    }
1144dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com}
1154dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com
1164dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.comvoid* FlattenableHeap::allocThrow(size_t bytes) {
1174dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com    void* ptr = sk_malloc_throw(bytes);
1184dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com    *fPointers.append() = ptr;
1194dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com    return ptr;
1204dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com}
1214dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com
1224dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.comconst SkFlatData* FlattenableHeap::flatToReplace() const {
1234dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com    // First, determine whether we should replace one.
1244dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com    if (fPointers.count() > fNumFlatsToKeep) {
1254dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com        // Look through the flattenable heap.
1264dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com        // TODO: Return the LRU flat.
1274dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com        for (int i = 0; i < fPointers.count(); i++) {
1284dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com            SkFlatData* potential = (SkFlatData*)fPointers[i];
1294dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com            // Make sure that it is not one that must be kept.
1304dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com            bool mustKeep = false;
1314dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com            for (int j = 0; j < fFlatsThatMustBeKept.count(); j++) {
1324dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com                if (potential->index() == fFlatsThatMustBeKept[j]) {
1334dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com                    mustKeep = true;
1344dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com                    break;
1354dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com                }
1364dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com            }
1374dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com            if (!mustKeep) {
1384dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com                return potential;
1394dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com            }
1404dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com        }
1414dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com    }
1424dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com    return NULL;
1434dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com}
1444dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com
1454dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com///////////////////////////////////////////////////////////////////////////////
1464dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com
1474dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.comclass FlatDictionary : public SkFlatDictionary<SkFlattenable> {
1484dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.compublic:
1491554360a9511d996e1618d19c163c810ef3f128cscroggo@google.com    FlatDictionary(FlattenableHeap* heap)
1501554360a9511d996e1618d19c163c810ef3f128cscroggo@google.com            : SkFlatDictionary<SkFlattenable>(heap) {
1514dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com        fFlattenProc = &flattenFlattenableProc;
1524dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com        // No need to define fUnflattenProc since the writer will never
1534dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com        // unflatten the data.
1544dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com    }
1554dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com    static void flattenFlattenableProc(SkOrderedWriteBuffer& buffer,
1564dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com                                       const void* obj) {
1574dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com        buffer.writeFlattenable((SkFlattenable*)obj);
1584dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com    }
1594dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com
1604dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com};
1614dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com
1624dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com///////////////////////////////////////////////////////////////////////////////
1634dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com
164bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comclass SkGPipeCanvas : public SkCanvas {
165bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.compublic:
166a8db8fe39a640bda4b85b9342c3b6b2525142afajunov@chromium.org    SkGPipeCanvas(SkGPipeController*, SkWriter32*, uint32_t flags,
167a8db8fe39a640bda4b85b9342c3b6b2525142afajunov@chromium.org                  uint32_t width, uint32_t height);
168bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    virtual ~SkGPipeCanvas();
169bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
170bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    void finish() {
171bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        if (!fDone) {
172dbccc88f84e5330ce6e52512fcefd375ee2eda49reed@google.com            if (this->needOpBytes()) {
173dbccc88f84e5330ce6e52512fcefd375ee2eda49reed@google.com                this->writeOp(kDone_DrawOp);
174dbccc88f84e5330ce6e52512fcefd375ee2eda49reed@google.com                this->doNotify();
1753e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com                if (shouldFlattenBitmaps(fFlags)) {
176d9d2967ce1cca98c7992ac034a6b6e0707c56051scroggo@google.com                    // In this case, a BitmapShuttle is reffed by the SkBitmapHeap
177d9d2967ce1cca98c7992ac034a6b6e0707c56051scroggo@google.com                    // and refs this canvas. Unref the SkBitmapHeap to end the
1783e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com                    // circular reference. When shouldFlattenBitmaps is false,
179d9d2967ce1cca98c7992ac034a6b6e0707c56051scroggo@google.com                    // there is no circular reference, so the SkBitmapHeap can be
1803e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com                    // safely unreffed in the destructor.
181d9d2967ce1cca98c7992ac034a6b6e0707c56051scroggo@google.com                    fBitmapHeap->unref();
1827ca24437c71af06fc06ab5f6f261b185882fa440scroggo@google.com                    // This eliminates a similar circular reference (Canvas owns
183d9d2967ce1cca98c7992ac034a6b6e0707c56051scroggo@google.com                    // the FlattenableHeap which holds a ref to the SkBitmapHeap).
1847ca24437c71af06fc06ab5f6f261b185882fa440scroggo@google.com                    fFlattenableHeap.setBitmapStorage(NULL);
185d9d2967ce1cca98c7992ac034a6b6e0707c56051scroggo@google.com                    fBitmapHeap = NULL;
1863e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com                }
187dbccc88f84e5330ce6e52512fcefd375ee2eda49reed@google.com            }
188bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com            fDone = true;
189bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        }
190bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
191bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
19277eec248cbd5a0c2f5f8595e62e3bff5ea363f17junov@chromium.org    void flushRecording(bool detachCurrentBlock);
1932e14ba8ceb41c68042ff133fecf0561a2c22efcajunov@chromium.org    size_t freeMemoryIfPossible(size_t bytesToFree);
19477eec248cbd5a0c2f5f8595e62e3bff5ea363f17junov@chromium.org
19515011ee5e4068ab6523e432e435473a822ee7d80scroggo@google.com    size_t storageAllocatedForRecording() {
196d5d158b325f05902ac845f2f7c8c65ffe6074257scroggo@google.com        return (NULL == fBitmapHeap) ? 0 : fBitmapHeap->bytesAllocated();
19715011ee5e4068ab6523e432e435473a822ee7d80scroggo@google.com    }
19815011ee5e4068ab6523e432e435473a822ee7d80scroggo@google.com
199bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    // overrides from SkCanvas
2003b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com    virtual int save(SaveFlags) SK_OVERRIDE;
2013b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com    virtual int saveLayer(const SkRect* bounds, const SkPaint*,
2023b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com                          SaveFlags) SK_OVERRIDE;
2033b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com    virtual void restore() SK_OVERRIDE;
204fbe9c8fbb8e74ad55694f8bb7fa5463708e94a6djunov@chromium.org    virtual bool isDrawingToLayer() const SK_OVERRIDE;
2053b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com    virtual bool translate(SkScalar dx, SkScalar dy) SK_OVERRIDE;
2063b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com    virtual bool scale(SkScalar sx, SkScalar sy) SK_OVERRIDE;
2073b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com    virtual bool rotate(SkScalar degrees) SK_OVERRIDE;
2083b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com    virtual bool skew(SkScalar sx, SkScalar sy) SK_OVERRIDE;
2093b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com    virtual bool concat(const SkMatrix& matrix) SK_OVERRIDE;
2103b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com    virtual void setMatrix(const SkMatrix& matrix) SK_OVERRIDE;
2113b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com    virtual bool clipRect(const SkRect& rect, SkRegion::Op op,
2123b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com                          bool doAntiAlias = false) SK_OVERRIDE;
2133b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com    virtual bool clipPath(const SkPath& path, SkRegion::Op op,
2143b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com                          bool doAntiAlias = false) SK_OVERRIDE;
2153b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com    virtual bool clipRegion(const SkRegion& region, SkRegion::Op op) SK_OVERRIDE;
2163b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com    virtual void clear(SkColor) SK_OVERRIDE;
2173b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com    virtual void drawPaint(const SkPaint& paint) SK_OVERRIDE;
218bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    virtual void drawPoints(PointMode, size_t count, const SkPoint pts[],
2193b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com                            const SkPaint&) SK_OVERRIDE;
2203b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com    virtual void drawRect(const SkRect& rect, const SkPaint&) SK_OVERRIDE;
2213b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com    virtual void drawPath(const SkPath& path, const SkPaint&) SK_OVERRIDE;
222bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    virtual void drawBitmap(const SkBitmap&, SkScalar left, SkScalar top,
2233b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com                            const SkPaint*) SK_OVERRIDE;
224bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    virtual void drawBitmapRect(const SkBitmap&, const SkIRect* src,
2253b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com                                const SkRect& dst, const SkPaint*) SK_OVERRIDE;
226bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    virtual void drawBitmapMatrix(const SkBitmap&, const SkMatrix&,
2273b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com                                  const SkPaint*) SK_OVERRIDE;
2285a2e879ef8a3720ac3f06fbc13dcdaeb179f30c3scroggo@google.com    virtual void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
2295a2e879ef8a3720ac3f06fbc13dcdaeb179f30c3scroggo@google.com                                const SkRect& dst, const SkPaint* paint = NULL) SK_OVERRIDE;
230bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    virtual void drawSprite(const SkBitmap&, int left, int top,
2313b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com                            const SkPaint*) SK_OVERRIDE;
23274b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org    virtual void drawText(const void* text, size_t byteLength, SkScalar x,
2333b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com                          SkScalar y, const SkPaint&) SK_OVERRIDE;
23474b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org    virtual void drawPosText(const void* text, size_t byteLength,
2353b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com                             const SkPoint pos[], const SkPaint&) SK_OVERRIDE;
236bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    virtual void drawPosTextH(const void* text, size_t byteLength,
2373b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com                              const SkScalar xpos[], SkScalar constY,
2383b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com                              const SkPaint&) SK_OVERRIDE;
23974b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org    virtual void drawTextOnPath(const void* text, size_t byteLength,
24074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org                            const SkPath& path, const SkMatrix* matrix,
2413b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com                                const SkPaint&) SK_OVERRIDE;
2423b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com    virtual void drawPicture(SkPicture& picture) SK_OVERRIDE;
243bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    virtual void drawVertices(VertexMode, int vertexCount,
244bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com                          const SkPoint vertices[], const SkPoint texs[],
245bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com                          const SkColor colors[], SkXfermode*,
246bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com                          const uint16_t indices[], int indexCount,
2473b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com                              const SkPaint&) SK_OVERRIDE;
2483b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com    virtual void drawData(const void*, size_t) SK_OVERRIDE;
249bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
2503e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com    /**
2513e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com     * Flatten an SkBitmap to send to the reader, where it will be referenced
2523e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com     * according to slot.
2533e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com     */
2543e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com    bool shuttleBitmap(const SkBitmap&, int32_t slot);
255bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comprivate:
256fbe9c8fbb8e74ad55694f8bb7fa5463708e94a6djunov@chromium.org    enum {
257fbe9c8fbb8e74ad55694f8bb7fa5463708e94a6djunov@chromium.org        kNoSaveLayer = -1,
258fbe9c8fbb8e74ad55694f8bb7fa5463708e94a6djunov@chromium.org    };
2590c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com    SkNamedFactorySet* fFactorySet;
2600c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com    int                fFirstSaveLayerStackLevel;
261d9d2967ce1cca98c7992ac034a6b6e0707c56051scroggo@google.com    SkBitmapHeap*      fBitmapHeap;
262acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    SkGPipeController* fController;
2630c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com    SkWriter32&        fWriter;
2640c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com    size_t             fBlockSize; // amount allocated for writer
2650c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com    size_t             fBytesNotified;
2660c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com    bool               fDone;
2673e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com    const uint32_t     fFlags;
268bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
2690c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com    SkRefCntSet        fTypefaceSet;
270f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com
271f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com    uint32_t getTypefaceID(SkTypeface*);
272f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com
273acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    inline void writeOp(DrawOps op, unsigned flags, unsigned data) {
274bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        fWriter.write32(DrawOp_packOpFlagData(op, flags, data));
275bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
27674b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org
277acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    inline void writeOp(DrawOps op) {
278bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        fWriter.write32(DrawOp_packOpFlagData(op, 0, 0));
279bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
280acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com
281acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    bool needOpBytes(size_t size = 0);
282acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com
283acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    inline void doNotify() {
284acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        if (!fDone) {
285acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            size_t bytes = fWriter.size() - fBytesNotified;
28616d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com            if (bytes > 0) {
28716d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com                fController->notifyWritten(bytes);
28816d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com                fBytesNotified += bytes;
28916d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com            }
290acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        }
291acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    }
292b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com
2930c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com    // Should be called after any calls to an SkFlatDictionary::findAndReplace
2940c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com    // if a new SkFlatData was added when in cross process mode
2950c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com    void flattenFactoryNames();
2960c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com
2974dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com    FlattenableHeap fFlattenableHeap;
2984dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com    FlatDictionary  fFlatDictionary;
299b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com    int fCurrFlatIndex[kCount_PaintFlats];
300b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com    int flattenToIndex(SkFlattenable* obj, PaintFlats);
301b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com
3023e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com    // Common code used by drawBitmap*. Behaves differently depending on the
3033e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com    // type of SkBitmapHeap being used, which is determined by the flags used.
3043e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com    bool commonDrawBitmap(const SkBitmap& bm, DrawOps op, unsigned flags,
3053e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com                          size_t opBytesNeeded, const SkPaint* paint);
30658be682c77c76d9a0caf23337f9b357798179b6cscroggo@google.com
30731891584fef10c88b39f6bf19ac5cde0a862b8c4reed@google.com    SkPaint fPaint;
30831891584fef10c88b39f6bf19ac5cde0a862b8c4reed@google.com    void writePaint(const SkPaint&);
309bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
310acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    class AutoPipeNotify {
311acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    public:
312acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        AutoPipeNotify(SkGPipeCanvas* canvas) : fCanvas(canvas) {}
313acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        ~AutoPipeNotify() { fCanvas->doNotify(); }
314acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    private:
315acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        SkGPipeCanvas* fCanvas;
316acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    };
317acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    friend class AutoPipeNotify;
318acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com
319bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    typedef SkCanvas INHERITED;
320bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com};
321bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
3220c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.comvoid SkGPipeCanvas::flattenFactoryNames() {
3230c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com    const char* name;
3240c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com    while ((name = fFactorySet->getNextAddedFactoryName()) != NULL) {
3250c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com        size_t len = strlen(name);
3260c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com        if (this->needOpBytes(len)) {
3270c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com            this->writeOp(kDef_Factory_DrawOp);
3280c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com            fWriter.writeString(name, len);
3290c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com        }
3300c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com    }
3310c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com}
3320c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com
3333e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.combool SkGPipeCanvas::shuttleBitmap(const SkBitmap& bm, int32_t slot) {
334565254bc9343d0befdfbbb97a3dc6d44c6e18658scroggo@google.com    SkASSERT(shouldFlattenBitmaps(fFlags));
3353e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com    SkOrderedWriteBuffer buffer(1024);
3363e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com    buffer.setNamedFactoryRecorder(fFactorySet);
3373e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com    bm.flatten(buffer);
3383e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com    this->flattenFactoryNames();
3393e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com    uint32_t size = buffer.size();
3403e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com    if (this->needOpBytes(size)) {
3413e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com        this->writeOp(kDef_Bitmap_DrawOp, 0, slot);
3423e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com        void* dst = static_cast<void*>(fWriter.reserve(size));
3433e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com        buffer.writeToMemory(dst);
3443e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com        return true;
3454dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com    }
3463e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com    return false;
347d3ba5cc85e24896f980ed1ba6e3f4495973baeb3scroggo@google.com}
348d3ba5cc85e24896f980ed1ba6e3f4495973baeb3scroggo@google.com
349b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com// return 0 for NULL (or unflattenable obj), or index-base-1
350d3ba5cc85e24896f980ed1ba6e3f4495973baeb3scroggo@google.com// return ~(index-base-1) if an old flattenable was replaced
351b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.comint SkGPipeCanvas::flattenToIndex(SkFlattenable* obj, PaintFlats paintflat) {
352d5d158b325f05902ac845f2f7c8c65ffe6074257scroggo@google.com    SkASSERT(!fDone && fBitmapHeap != NULL);
353b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com    if (NULL == obj) {
354b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com        return 0;
355b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com    }
356b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com
357d9d2967ce1cca98c7992ac034a6b6e0707c56051scroggo@google.com    fBitmapHeap->deferAddingOwners();
3584dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com    bool added, replaced;
359664fab1b3454faea01cbae2f1dc2777c5afb9998scroggo@google.com    const SkFlatData* flat = fFlatDictionary.findAndReplace(*obj, fFlattenableHeap.flatToReplace(),
360664fab1b3454faea01cbae2f1dc2777c5afb9998scroggo@google.com                                                            &added, &replaced);
361d9d2967ce1cca98c7992ac034a6b6e0707c56051scroggo@google.com    fBitmapHeap->endAddingOwnersDeferral(added);
3624dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com    int index = flat->index();
3630c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com    if (added) {
3640c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com        if (isCrossProcess(fFlags)) {
3650c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com            this->flattenFactoryNames();
3660c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com        }
3670c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com        size_t flatSize = flat->flatSize();
3680c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com        if (this->needOpBytes(flatSize)) {
3690c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com            this->writeOp(kDef_Flattenable_DrawOp, paintflat, index);
3700c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com            fWriter.write(flat->data(), flatSize);
3710c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com        }
372b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com    }
3734dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com    if (replaced) {
3744dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com        index = ~index;
375d3ba5cc85e24896f980ed1ba6e3f4495973baeb3scroggo@google.com    }
3764dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com    return index;
377b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com}
378b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com
379bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com///////////////////////////////////////////////////////////////////////////////
380bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
3813e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com/**
3823e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com * If SkBitmaps are to be flattened to send to the reader, this class is
3833e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com * provided to the SkBitmapHeap to tell the SkGPipeCanvas to do so.
3843e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com */
3853e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.comclass BitmapShuttle : public SkBitmapHeap::ExternalStorage {
3863e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.compublic:
3873e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com    BitmapShuttle(SkGPipeCanvas*);
388d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
3893e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com    ~BitmapShuttle();
390d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
3913e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com    virtual bool insert(const SkBitmap& bitmap, int32_t slot) SK_OVERRIDE;
392d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
3933e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.comprivate:
3943e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com    SkGPipeCanvas*    fCanvas;
3953e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com};
3963e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com
3973e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com///////////////////////////////////////////////////////////////////////////////
3983e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com
399acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com#define MIN_BLOCK_SIZE  (16 * 1024)
4004dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com#define BITMAPS_TO_KEEP 5
4014dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com#define FLATTENABLES_TO_KEEP 10
402bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
403acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.comSkGPipeCanvas::SkGPipeCanvas(SkGPipeController* controller,
404d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com                             SkWriter32* writer, uint32_t flags,
405a8db8fe39a640bda4b85b9342c3b6b2525142afajunov@chromium.org                             uint32_t width, uint32_t height)
4060c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com: fFactorySet(isCrossProcess(flags) ? SkNEW(SkNamedFactorySet) : NULL)
4070c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com, fWriter(*writer)
4080c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com, fFlags(flags)
409664fab1b3454faea01cbae2f1dc2777c5afb9998scroggo@google.com, fFlattenableHeap(FLATTENABLES_TO_KEEP, fFactorySet, isCrossProcess(flags))
4101554360a9511d996e1618d19c163c810ef3f128cscroggo@google.com, fFlatDictionary(&fFlattenableHeap) {
411acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    fController = controller;
412bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    fDone = false;
413acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    fBlockSize = 0; // need first block from controller
4145a2e879ef8a3720ac3f06fbc13dcdaeb179f30c3scroggo@google.com    fBytesNotified = 0;
415fbe9c8fbb8e74ad55694f8bb7fa5463708e94a6djunov@chromium.org    fFirstSaveLayerStackLevel = kNoSaveLayer;
416b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com    sk_bzero(fCurrFlatIndex, sizeof(fCurrFlatIndex));
417acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com
418bb6793bd7751f7a4e48c942567cd6c5270661a2freed@google.com    // we need a device to limit our clip
41906b4da16fd6ed63560d79116c6066534e953a43dyangsu@google.com    // We don't allocate pixels for the bitmap
420bb6793bd7751f7a4e48c942567cd6c5270661a2freed@google.com    SkBitmap bitmap;
421a8db8fe39a640bda4b85b9342c3b6b2525142afajunov@chromium.org    bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height);
42206b4da16fd6ed63560d79116c6066534e953a43dyangsu@google.com    SkDevice* device = SkNEW_ARGS(SkDevice, (bitmap));
423bb6793bd7751f7a4e48c942567cd6c5270661a2freed@google.com    this->setDevice(device)->unref();
42410dccde54a769b8d472bccf8c1993034b93ef58dscroggo@google.com
425565254bc9343d0befdfbbb97a3dc6d44c6e18658scroggo@google.com    // Tell the reader the appropriate flags to use.
426565254bc9343d0befdfbbb97a3dc6d44c6e18658scroggo@google.com    if (this->needOpBytes()) {
427565254bc9343d0befdfbbb97a3dc6d44c6e18658scroggo@google.com        this->writeOp(kReportFlags_DrawOp, fFlags, 0);
428565254bc9343d0befdfbbb97a3dc6d44c6e18658scroggo@google.com    }
429d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
43010dccde54a769b8d472bccf8c1993034b93ef58dscroggo@google.com    if (shouldFlattenBitmaps(flags)) {
4313e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com        BitmapShuttle* shuttle = SkNEW_ARGS(BitmapShuttle, (this));
432d9d2967ce1cca98c7992ac034a6b6e0707c56051scroggo@google.com        fBitmapHeap = SkNEW_ARGS(SkBitmapHeap, (shuttle, BITMAPS_TO_KEEP));
4333e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com        shuttle->unref();
43410dccde54a769b8d472bccf8c1993034b93ef58dscroggo@google.com    } else {
435d9d2967ce1cca98c7992ac034a6b6e0707c56051scroggo@google.com        fBitmapHeap = SkNEW_ARGS(SkBitmapHeap,
4363e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com                                 (BITMAPS_TO_KEEP, controller->numberOfReaders()));
43710dccde54a769b8d472bccf8c1993034b93ef58dscroggo@google.com        if (this->needOpBytes(sizeof(void*))) {
438d9d2967ce1cca98c7992ac034a6b6e0707c56051scroggo@google.com            this->writeOp(kShareBitmapHeap_DrawOp);
439d9d2967ce1cca98c7992ac034a6b6e0707c56051scroggo@google.com            fWriter.writePtr(static_cast<void*>(fBitmapHeap));
44010dccde54a769b8d472bccf8c1993034b93ef58dscroggo@google.com        }
44110dccde54a769b8d472bccf8c1993034b93ef58dscroggo@google.com    }
442d9d2967ce1cca98c7992ac034a6b6e0707c56051scroggo@google.com    fFlattenableHeap.setBitmapStorage(fBitmapHeap);
44310dccde54a769b8d472bccf8c1993034b93ef58dscroggo@google.com    this->doNotify();
444bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
445bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
446bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comSkGPipeCanvas::~SkGPipeCanvas() {
447bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    this->finish();
4480c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com    SkSafeUnref(fFactorySet);
449d9d2967ce1cca98c7992ac034a6b6e0707c56051scroggo@google.com    SkSafeUnref(fBitmapHeap);
450bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
451bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
452acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.combool SkGPipeCanvas::needOpBytes(size_t needed) {
453acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    if (fDone) {
454acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        return false;
455acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    }
456acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com
457acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    needed += 4;  // size of DrawOp atom
458acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    if (fWriter.size() + needed > fBlockSize) {
4595a2e879ef8a3720ac3f06fbc13dcdaeb179f30c3scroggo@google.com        // Before we wipe out any data that has already been written, read it
4605a2e879ef8a3720ac3f06fbc13dcdaeb179f30c3scroggo@google.com        // out.
4615a2e879ef8a3720ac3f06fbc13dcdaeb179f30c3scroggo@google.com        this->doNotify();
4625a2e879ef8a3720ac3f06fbc13dcdaeb179f30c3scroggo@google.com        size_t blockSize = SkMax32(MIN_BLOCK_SIZE, needed);
4635a2e879ef8a3720ac3f06fbc13dcdaeb179f30c3scroggo@google.com        void* block = fController->requestBlock(blockSize, &fBlockSize);
464acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        if (NULL == block) {
465acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fDone = true;
466acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            return false;
467acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        }
468460a23e6fd6b71c80d5515300c6b989cd3383029scroggo@google.com        SkASSERT(SkIsAlign4(fBlockSize));
469acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        fWriter.reset(block, fBlockSize);
470acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        fBytesNotified = 0;
471acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    }
472acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    return true;
473acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com}
474acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com
475f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.comuint32_t SkGPipeCanvas::getTypefaceID(SkTypeface* face) {
476f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com    uint32_t id = 0; // 0 means default/null typeface
477f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com    if (face) {
478f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com        id = fTypefaceSet.find(face);
479f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com        if (0 == id) {
480f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com            id = fTypefaceSet.add(face);
481f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com            size_t size = writeTypeface(NULL, face);
482f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com            if (this->needOpBytes(size)) {
483bb6793bd7751f7a4e48c942567cd6c5270661a2freed@google.com                this->writeOp(kDef_Typeface_DrawOp);
484f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com                writeTypeface(&fWriter, face);
485f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com            }
486f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com        }
487f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com    }
488f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com    return id;
489f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com}
490f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com
491bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com///////////////////////////////////////////////////////////////////////////////
492bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
493acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com#define NOTIFY_SETUP(canvas)    \
494acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    AutoPipeNotify apn(canvas)
495acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com
496bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comint SkGPipeCanvas::save(SaveFlags flags) {
497acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    NOTIFY_SETUP(this);
498acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    if (this->needOpBytes()) {
499acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        this->writeOp(kSave_DrawOp, 0, flags);
500acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    }
501bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    return this->INHERITED::save(flags);
502bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
503bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
504bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comint SkGPipeCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint,
505bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com                             SaveFlags saveFlags) {
506acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    NOTIFY_SETUP(this);
507acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    size_t size = 0;
508bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    unsigned opFlags = 0;
50974b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org
510bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (bounds) {
511bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        opFlags |= kSaveLayer_HasBounds_DrawOpFlag;
512acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        size += sizeof(SkRect);
513bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
514bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (paint) {
515bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        opFlags |= kSaveLayer_HasPaint_DrawOpFlag;
51631891584fef10c88b39f6bf19ac5cde0a862b8c4reed@google.com        this->writePaint(*paint);
517bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
518bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
519acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    if (this->needOpBytes(size)) {
520acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        this->writeOp(kSaveLayer_DrawOp, opFlags, saveFlags);
521acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        if (bounds) {
522acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.writeRect(*bounds);
523acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        }
524bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
52574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org
526fbe9c8fbb8e74ad55694f8bb7fa5463708e94a6djunov@chromium.org    if (kNoSaveLayer == fFirstSaveLayerStackLevel){
527fbe9c8fbb8e74ad55694f8bb7fa5463708e94a6djunov@chromium.org        fFirstSaveLayerStackLevel = this->getSaveCount();
528fbe9c8fbb8e74ad55694f8bb7fa5463708e94a6djunov@chromium.org    }
529bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    // we just pass on the save, so we don't create a layer
530bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    return this->INHERITED::save(saveFlags);
531bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
532bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
533bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comvoid SkGPipeCanvas::restore() {
534acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    NOTIFY_SETUP(this);
535acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    if (this->needOpBytes()) {
536acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        this->writeOp(kRestore_DrawOp);
537acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    }
538fbe9c8fbb8e74ad55694f8bb7fa5463708e94a6djunov@chromium.org
539bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    this->INHERITED::restore();
540fbe9c8fbb8e74ad55694f8bb7fa5463708e94a6djunov@chromium.org
541fbe9c8fbb8e74ad55694f8bb7fa5463708e94a6djunov@chromium.org    if (this->getSaveCount() == fFirstSaveLayerStackLevel){
542fbe9c8fbb8e74ad55694f8bb7fa5463708e94a6djunov@chromium.org        fFirstSaveLayerStackLevel = kNoSaveLayer;
543fbe9c8fbb8e74ad55694f8bb7fa5463708e94a6djunov@chromium.org    }
544fbe9c8fbb8e74ad55694f8bb7fa5463708e94a6djunov@chromium.org}
545fbe9c8fbb8e74ad55694f8bb7fa5463708e94a6djunov@chromium.org
546fbe9c8fbb8e74ad55694f8bb7fa5463708e94a6djunov@chromium.orgbool SkGPipeCanvas::isDrawingToLayer() const {
547fbe9c8fbb8e74ad55694f8bb7fa5463708e94a6djunov@chromium.org    return kNoSaveLayer != fFirstSaveLayerStackLevel;
548bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
549bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
550bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.combool SkGPipeCanvas::translate(SkScalar dx, SkScalar dy) {
551bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (dx || dy) {
552acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        NOTIFY_SETUP(this);
553acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        if (this->needOpBytes(2 * sizeof(SkScalar))) {
554acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            this->writeOp(kTranslate_DrawOp);
555acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.writeScalar(dx);
556acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.writeScalar(dy);
557acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        }
558bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
559bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    return this->INHERITED::translate(dx, dy);
560bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
561bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
562bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.combool SkGPipeCanvas::scale(SkScalar sx, SkScalar sy) {
563bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (sx || sy) {
564acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        NOTIFY_SETUP(this);
565acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        if (this->needOpBytes(2 * sizeof(SkScalar))) {
566acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            this->writeOp(kScale_DrawOp);
567acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.writeScalar(sx);
568acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.writeScalar(sy);
569acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        }
570bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
571bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    return this->INHERITED::scale(sx, sy);
572bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
573bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
574bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.combool SkGPipeCanvas::rotate(SkScalar degrees) {
575bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (degrees) {
576acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        NOTIFY_SETUP(this);
577acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        if (this->needOpBytes(sizeof(SkScalar))) {
578acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            this->writeOp(kRotate_DrawOp);
579acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.writeScalar(degrees);
580acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        }
581bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
582bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    return this->INHERITED::rotate(degrees);
583bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
584bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
585bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.combool SkGPipeCanvas::skew(SkScalar sx, SkScalar sy) {
586bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (sx || sy) {
587acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        NOTIFY_SETUP(this);
588acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        if (this->needOpBytes(2 * sizeof(SkScalar))) {
589acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            this->writeOp(kSkew_DrawOp);
590acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.writeScalar(sx);
591acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.writeScalar(sy);
592acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        }
593bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
594bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    return this->INHERITED::skew(sx, sy);
595bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
596bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
597bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.combool SkGPipeCanvas::concat(const SkMatrix& matrix) {
598bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (!matrix.isIdentity()) {
599acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        NOTIFY_SETUP(this);
60094e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com        if (this->needOpBytes(matrix.writeToMemory(NULL))) {
601acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            this->writeOp(kConcat_DrawOp);
6022b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com            fWriter.writeMatrix(matrix);
603acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        }
604bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
605bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    return this->INHERITED::concat(matrix);
606bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
607bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
608bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comvoid SkGPipeCanvas::setMatrix(const SkMatrix& matrix) {
609acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    NOTIFY_SETUP(this);
61094e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com    if (this->needOpBytes(matrix.writeToMemory(NULL))) {
611acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        this->writeOp(kSetMatrix_DrawOp);
6122b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com        fWriter.writeMatrix(matrix);
613acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    }
614bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    this->INHERITED::setMatrix(matrix);
615bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
616bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
6173b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.combool SkGPipeCanvas::clipRect(const SkRect& rect, SkRegion::Op rgnOp,
6183b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com                             bool doAntiAlias) {
619acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    NOTIFY_SETUP(this);
620460a23e6fd6b71c80d5515300c6b989cd3383029scroggo@google.com    if (this->needOpBytes(sizeof(SkRect))) {
621460a23e6fd6b71c80d5515300c6b989cd3383029scroggo@google.com        unsigned flags = doAntiAlias & kClip_HasAntiAlias_DrawOpFlag;
622460a23e6fd6b71c80d5515300c6b989cd3383029scroggo@google.com        this->writeOp(kClipRect_DrawOp, flags, rgnOp);
623acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        fWriter.writeRect(rect);
624acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    }
6253b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com    return this->INHERITED::clipRect(rect, rgnOp, doAntiAlias);
626bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
627bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
6283b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.combool SkGPipeCanvas::clipPath(const SkPath& path, SkRegion::Op rgnOp,
6293b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com                             bool doAntiAlias) {
630acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    NOTIFY_SETUP(this);
631460a23e6fd6b71c80d5515300c6b989cd3383029scroggo@google.com    if (this->needOpBytes(path.writeToMemory(NULL))) {
632460a23e6fd6b71c80d5515300c6b989cd3383029scroggo@google.com        unsigned flags = doAntiAlias & kClip_HasAntiAlias_DrawOpFlag;
633460a23e6fd6b71c80d5515300c6b989cd3383029scroggo@google.com        this->writeOp(kClipPath_DrawOp, flags, rgnOp);
63494e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com        fWriter.writePath(path);
635acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    }
636bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    // we just pass on the bounds of the path
6373b45cd53f0c4c9b810b6383f529a72ecfa4e6e7fscroggo@google.com    return this->INHERITED::clipRect(path.getBounds(), rgnOp, doAntiAlias);
638bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
639bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
640bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.combool SkGPipeCanvas::clipRegion(const SkRegion& region, SkRegion::Op rgnOp) {
641acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    NOTIFY_SETUP(this);
64294e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com    if (this->needOpBytes(region.writeToMemory(NULL))) {
643acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        this->writeOp(kClipRegion_DrawOp, 0, rgnOp);
6442b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com        fWriter.writeRegion(region);
645acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    }
646bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    return this->INHERITED::clipRegion(region, rgnOp);
647bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
648bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
649bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com///////////////////////////////////////////////////////////////////////////////
650bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
651bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comvoid SkGPipeCanvas::clear(SkColor color) {
652acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    NOTIFY_SETUP(this);
653bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    unsigned flags = 0;
654bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (color) {
655bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        flags |= kClear_HasColor_DrawOpFlag;
656bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
657acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    if (this->needOpBytes(sizeof(SkColor))) {
658acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        this->writeOp(kDrawClear_DrawOp, flags, 0);
659acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        if (color) {
660acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.write32(color);
661acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        }
662bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
663bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
664bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
665bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comvoid SkGPipeCanvas::drawPaint(const SkPaint& paint) {
666acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    NOTIFY_SETUP(this);
66731891584fef10c88b39f6bf19ac5cde0a862b8c4reed@google.com    this->writePaint(paint);
668acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    if (this->needOpBytes()) {
66931891584fef10c88b39f6bf19ac5cde0a862b8c4reed@google.com        this->writeOp(kDrawPaint_DrawOp);
670acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    }
671bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
672bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
673bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comvoid SkGPipeCanvas::drawPoints(PointMode mode, size_t count,
674bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com                                   const SkPoint pts[], const SkPaint& paint) {
675bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (count) {
676acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        NOTIFY_SETUP(this);
67731891584fef10c88b39f6bf19ac5cde0a862b8c4reed@google.com        this->writePaint(paint);
678acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        if (this->needOpBytes(4 + count * sizeof(SkPoint))) {
67931891584fef10c88b39f6bf19ac5cde0a862b8c4reed@google.com            this->writeOp(kDrawPoints_DrawOp, mode, 0);
680acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.write32(count);
681acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.write(pts, count * sizeof(SkPoint));
682acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        }
683bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
684bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
685bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
686bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comvoid SkGPipeCanvas::drawRect(const SkRect& rect, const SkPaint& paint) {
687acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    NOTIFY_SETUP(this);
68831891584fef10c88b39f6bf19ac5cde0a862b8c4reed@google.com    this->writePaint(paint);
689acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    if (this->needOpBytes(sizeof(SkRect))) {
69031891584fef10c88b39f6bf19ac5cde0a862b8c4reed@google.com        this->writeOp(kDrawRect_DrawOp);
691acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        fWriter.writeRect(rect);
692acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    }
693bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
694bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
695bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comvoid SkGPipeCanvas::drawPath(const SkPath& path, const SkPaint& paint) {
696acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    NOTIFY_SETUP(this);
69731891584fef10c88b39f6bf19ac5cde0a862b8c4reed@google.com    this->writePaint(paint);
69894e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com    if (this->needOpBytes(path.writeToMemory(NULL))) {
69931891584fef10c88b39f6bf19ac5cde0a862b8c4reed@google.com        this->writeOp(kDrawPath_DrawOp);
70094e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com        fWriter.writePath(path);
701acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    }
702bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
703bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
7043e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.combool SkGPipeCanvas::commonDrawBitmap(const SkBitmap& bm, DrawOps op,
7053e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com                                     unsigned flags,
7063e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com                                     size_t opBytesNeeded,
7073e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com                                     const SkPaint* paint) {
70858be682c77c76d9a0caf23337f9b357798179b6cscroggo@google.com    if (paint != NULL) {
709460a23e6fd6b71c80d5515300c6b989cd3383029scroggo@google.com        flags |= kDrawBitmap_HasPaint_DrawOpFlag;
7105a2e879ef8a3720ac3f06fbc13dcdaeb179f30c3scroggo@google.com        this->writePaint(*paint);
7115a2e879ef8a3720ac3f06fbc13dcdaeb179f30c3scroggo@google.com    }
71210dccde54a769b8d472bccf8c1993034b93ef58dscroggo@google.com    if (this->needOpBytes(opBytesNeeded)) {
713d5d158b325f05902ac845f2f7c8c65ffe6074257scroggo@google.com        SkASSERT(fBitmapHeap != NULL);
714d5d158b325f05902ac845f2f7c8c65ffe6074257scroggo@google.com        int32_t bitmapIndex = fBitmapHeap->insert(bm);
715d5d158b325f05902ac845f2f7c8c65ffe6074257scroggo@google.com        if (SkBitmapHeap::INVALID_SLOT == bitmapIndex) {
716d5d158b325f05902ac845f2f7c8c65ffe6074257scroggo@google.com            return false;
717d5d158b325f05902ac845f2f7c8c65ffe6074257scroggo@google.com        }
71810dccde54a769b8d472bccf8c1993034b93ef58dscroggo@google.com        this->writeOp(op, flags, bitmapIndex);
71958be682c77c76d9a0caf23337f9b357798179b6cscroggo@google.com        return true;
720565254bc9343d0befdfbbb97a3dc6d44c6e18658scroggo@google.com    }
72158be682c77c76d9a0caf23337f9b357798179b6cscroggo@google.com    return false;
72258be682c77c76d9a0caf23337f9b357798179b6cscroggo@google.com}
72358be682c77c76d9a0caf23337f9b357798179b6cscroggo@google.com
72458be682c77c76d9a0caf23337f9b357798179b6cscroggo@google.comvoid SkGPipeCanvas::drawBitmap(const SkBitmap& bm, SkScalar left, SkScalar top,
72558be682c77c76d9a0caf23337f9b357798179b6cscroggo@google.com                               const SkPaint* paint) {
72658be682c77c76d9a0caf23337f9b357798179b6cscroggo@google.com    NOTIFY_SETUP(this);
72758be682c77c76d9a0caf23337f9b357798179b6cscroggo@google.com    size_t opBytesNeeded = sizeof(SkScalar) * 2;
72858be682c77c76d9a0caf23337f9b357798179b6cscroggo@google.com
7293e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com    if (this->commonDrawBitmap(bm, kDrawBitmap_DrawOp, 0, opBytesNeeded, paint)) {
7305a2e879ef8a3720ac3f06fbc13dcdaeb179f30c3scroggo@google.com        fWriter.writeScalar(left);
7315a2e879ef8a3720ac3f06fbc13dcdaeb179f30c3scroggo@google.com        fWriter.writeScalar(top);
7325a2e879ef8a3720ac3f06fbc13dcdaeb179f30c3scroggo@google.com    }
733bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
734bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
73516d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.comvoid SkGPipeCanvas::drawBitmapRect(const SkBitmap& bm, const SkIRect* src,
73658be682c77c76d9a0caf23337f9b357798179b6cscroggo@google.com                                   const SkRect& dst, const SkPaint* paint) {
73716d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com    NOTIFY_SETUP(this);
73858be682c77c76d9a0caf23337f9b357798179b6cscroggo@google.com    size_t opBytesNeeded = sizeof(SkRect);
73916d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com    bool hasSrc = src != NULL;
74058be682c77c76d9a0caf23337f9b357798179b6cscroggo@google.com    unsigned flags;
74116d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com    if (hasSrc) {
742460a23e6fd6b71c80d5515300c6b989cd3383029scroggo@google.com        flags = kDrawBitmap_HasSrcRect_DrawOpFlag;
74316d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com        opBytesNeeded += sizeof(int32_t) * 4;
74458be682c77c76d9a0caf23337f9b357798179b6cscroggo@google.com    } else {
74558be682c77c76d9a0caf23337f9b357798179b6cscroggo@google.com        flags = 0;
74616d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com    }
747d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
7483e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com    if (this->commonDrawBitmap(bm, kDrawBitmapRect_DrawOp, flags, opBytesNeeded, paint)) {
74916d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com        if (hasSrc) {
75016d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com            fWriter.write32(src->fLeft);
75116d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com            fWriter.write32(src->fTop);
75216d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com            fWriter.write32(src->fRight);
75316d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com            fWriter.write32(src->fBottom);
75416d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com        }
75516d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com        fWriter.writeRect(dst);
75616d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com    }
757bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
758bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
75958be682c77c76d9a0caf23337f9b357798179b6cscroggo@google.comvoid SkGPipeCanvas::drawBitmapMatrix(const SkBitmap& bm, const SkMatrix& matrix,
76058be682c77c76d9a0caf23337f9b357798179b6cscroggo@google.com                                     const SkPaint* paint) {
76158be682c77c76d9a0caf23337f9b357798179b6cscroggo@google.com    NOTIFY_SETUP(this);
76258be682c77c76d9a0caf23337f9b357798179b6cscroggo@google.com    size_t opBytesNeeded = matrix.writeToMemory(NULL);
763d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
7643e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com    if (this->commonDrawBitmap(bm, kDrawBitmapMatrix_DrawOp, 0, opBytesNeeded, paint)) {
76558be682c77c76d9a0caf23337f9b357798179b6cscroggo@google.com        fWriter.writeMatrix(matrix);
76658be682c77c76d9a0caf23337f9b357798179b6cscroggo@google.com    }
767bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
76816d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com
76916d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.comvoid SkGPipeCanvas::drawBitmapNine(const SkBitmap& bm, const SkIRect& center,
7705a2e879ef8a3720ac3f06fbc13dcdaeb179f30c3scroggo@google.com                                   const SkRect& dst, const SkPaint* paint) {
77116d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com    NOTIFY_SETUP(this);
77258be682c77c76d9a0caf23337f9b357798179b6cscroggo@google.com    size_t opBytesNeeded = sizeof(int32_t) * 4 + sizeof(SkRect);
77316d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com
7743e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com    if (this->commonDrawBitmap(bm, kDrawBitmapNine_DrawOp, 0, opBytesNeeded, paint)) {
77516d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com        fWriter.write32(center.fLeft);
77616d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com        fWriter.write32(center.fTop);
77716d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com        fWriter.write32(center.fRight);
77816d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com        fWriter.write32(center.fBottom);
77916d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com        fWriter.writeRect(dst);
78016d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com    }
7815a2e879ef8a3720ac3f06fbc13dcdaeb179f30c3scroggo@google.com}
78216d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com
78316d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.comvoid SkGPipeCanvas::drawSprite(const SkBitmap& bm, int left, int top,
78416d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com                                   const SkPaint* paint) {
78516d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com    NOTIFY_SETUP(this);
78658be682c77c76d9a0caf23337f9b357798179b6cscroggo@google.com    size_t opBytesNeeded = sizeof(int32_t) * 2;
78716d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com
7883e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com    if (this->commonDrawBitmap(bm, kDrawSprite_DrawOp, 0, opBytesNeeded, paint)) {
78916d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com        fWriter.write32(left);
79016d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com        fWriter.write32(top);
79116d1d0b39a78fa4ab4fbd6ed3296cf010ea9a61cscroggo@google.com    }
792bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
793bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
79474b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.orgvoid SkGPipeCanvas::drawText(const void* text, size_t byteLength, SkScalar x,
795bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com                                 SkScalar y, const SkPaint& paint) {
796bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (byteLength) {
797acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        NOTIFY_SETUP(this);
79831891584fef10c88b39f6bf19ac5cde0a862b8c4reed@google.com        this->writePaint(paint);
799acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        if (this->needOpBytes(4 + SkAlign4(byteLength) + 2 * sizeof(SkScalar))) {
80031891584fef10c88b39f6bf19ac5cde0a862b8c4reed@google.com            this->writeOp(kDrawText_DrawOp);
801acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.write32(byteLength);
802acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.writePad(text, byteLength);
803acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.writeScalar(x);
804acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.writeScalar(y);
805acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        }
806bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
807bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
808bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
80974b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.orgvoid SkGPipeCanvas::drawPosText(const void* text, size_t byteLength,
810bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com                                const SkPoint pos[], const SkPaint& paint) {
811bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (byteLength) {
812acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        NOTIFY_SETUP(this);
81331891584fef10c88b39f6bf19ac5cde0a862b8c4reed@google.com        this->writePaint(paint);
814bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        int count = paint.textToGlyphs(text, byteLength, NULL);
815acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        if (this->needOpBytes(4 + SkAlign4(byteLength) + 4 + count * sizeof(SkPoint))) {
81631891584fef10c88b39f6bf19ac5cde0a862b8c4reed@google.com            this->writeOp(kDrawPosText_DrawOp);
817acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.write32(byteLength);
818acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.writePad(text, byteLength);
819acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.write32(count);
820acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.write(pos, count * sizeof(SkPoint));
821acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        }
822bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
823bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
824bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
825bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comvoid SkGPipeCanvas::drawPosTextH(const void* text, size_t byteLength,
826bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com                                 const SkScalar xpos[], SkScalar constY,
827bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com                                 const SkPaint& paint) {
828bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (byteLength) {
829acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        NOTIFY_SETUP(this);
83031891584fef10c88b39f6bf19ac5cde0a862b8c4reed@google.com        this->writePaint(paint);
831bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        int count = paint.textToGlyphs(text, byteLength, NULL);
832acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        if (this->needOpBytes(4 + SkAlign4(byteLength) + 4 + count * sizeof(SkScalar) + 4)) {
83331891584fef10c88b39f6bf19ac5cde0a862b8c4reed@google.com            this->writeOp(kDrawPosTextH_DrawOp);
834acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.write32(byteLength);
835acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.writePad(text, byteLength);
836acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.write32(count);
837acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.write(xpos, count * sizeof(SkScalar));
838acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.writeScalar(constY);
839acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        }
840bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
841bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
842bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
84374b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.orgvoid SkGPipeCanvas::drawTextOnPath(const void* text, size_t byteLength,
84474b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org                                   const SkPath& path, const SkMatrix* matrix,
845bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com                                   const SkPaint& paint) {
846bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (byteLength) {
847acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        NOTIFY_SETUP(this);
848bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        unsigned flags = 0;
84994e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com        size_t size = 4 + SkAlign4(byteLength) + path.writeToMemory(NULL);
850bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        if (matrix) {
851bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com            flags |= kDrawTextOnPath_HasMatrix_DrawOpFlag;
85294e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com            size += matrix->writeToMemory(NULL);
853bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        }
85431891584fef10c88b39f6bf19ac5cde0a862b8c4reed@google.com        this->writePaint(paint);
855acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        if (this->needOpBytes(size)) {
85631891584fef10c88b39f6bf19ac5cde0a862b8c4reed@google.com            this->writeOp(kDrawTextOnPath_DrawOp, flags, 0);
857bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
858acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.write32(byteLength);
859acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.writePad(text, byteLength);
860bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
86194e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com            fWriter.writePath(path);
862acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            if (matrix) {
8632b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com                fWriter.writeMatrix(*matrix);
864acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            }
865bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        }
866bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
867bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
868bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
869bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comvoid SkGPipeCanvas::drawPicture(SkPicture& picture) {
8700faac1e8579088a39f38d02ff675f14d7deb608dreed@google.com    // we want to playback the picture into individual draw calls
8710faac1e8579088a39f38d02ff675f14d7deb608dreed@google.com    this->INHERITED::drawPicture(picture);
872bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
873bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
874bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comvoid SkGPipeCanvas::drawVertices(VertexMode mode, int vertexCount,
875bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com                                 const SkPoint vertices[], const SkPoint texs[],
876bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com                                 const SkColor colors[], SkXfermode*,
877bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com                                 const uint16_t indices[], int indexCount,
878bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com                                 const SkPaint& paint) {
879bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (0 == vertexCount) {
880bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        return;
881bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
882bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
883acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    NOTIFY_SETUP(this);
884acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    size_t size = 4 + vertexCount * sizeof(SkPoint);
88531891584fef10c88b39f6bf19ac5cde0a862b8c4reed@google.com    this->writePaint(paint);
886bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    unsigned flags = 0;
887bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (texs) {
888bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        flags |= kDrawVertices_HasTexs_DrawOpFlag;
889acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        size += vertexCount * sizeof(SkPoint);
890bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
891bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (colors) {
892bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        flags |= kDrawVertices_HasColors_DrawOpFlag;
893acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        size += vertexCount * sizeof(SkColor);
894bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
895bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (indices && indexCount > 0) {
896bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        flags |= kDrawVertices_HasIndices_DrawOpFlag;
897acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        size += 4 + SkAlign4(indexCount * sizeof(uint16_t));
898bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
89974b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org
900acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    if (this->needOpBytes(size)) {
90131891584fef10c88b39f6bf19ac5cde0a862b8c4reed@google.com        this->writeOp(kDrawVertices_DrawOp, flags, 0);
902acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        fWriter.write32(mode);
903acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        fWriter.write32(vertexCount);
904acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        fWriter.write(vertices, vertexCount * sizeof(SkPoint));
905acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        if (texs) {
906acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.write(texs, vertexCount * sizeof(SkPoint));
907acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        }
908acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        if (colors) {
909acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.write(colors, vertexCount * sizeof(SkColor));
910acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        }
911bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
912acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        // TODO: flatten xfermode
913bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
914acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        if (indices && indexCount > 0) {
915acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.write32(indexCount);
916acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            fWriter.writePad(indices, indexCount * sizeof(uint16_t));
917acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        }
918bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
919bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
920bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
921acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.comvoid SkGPipeCanvas::drawData(const void* ptr, size_t size) {
922acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    if (size && ptr) {
923acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        NOTIFY_SETUP(this);
924bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        unsigned data = 0;
925bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        if (size < (1 << DRAWOPS_DATA_BITS)) {
926bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com            data = (unsigned)size;
927bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        }
928acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        if (this->needOpBytes(4 + SkAlign4(size))) {
929acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            this->writeOp(kDrawData_DrawOp, 0, data);
930acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            if (0 == data) {
931acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com                fWriter.write32(size);
932acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com            }
933bb6793bd7751f7a4e48c942567cd6c5270661a2freed@google.com            fWriter.writePad(ptr, size);
934bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        }
935bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
936bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
937bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
93877eec248cbd5a0c2f5f8595e62e3bff5ea363f17junov@chromium.orgvoid SkGPipeCanvas::flushRecording(bool detachCurrentBlock) {
93977eec248cbd5a0c2f5f8595e62e3bff5ea363f17junov@chromium.org    doNotify();
94077eec248cbd5a0c2f5f8595e62e3bff5ea363f17junov@chromium.org    if (detachCurrentBlock) {
94177eec248cbd5a0c2f5f8595e62e3bff5ea363f17junov@chromium.org        // force a new block to be requested for the next recorded command
942d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        fBlockSize = 0;
94377eec248cbd5a0c2f5f8595e62e3bff5ea363f17junov@chromium.org    }
94477eec248cbd5a0c2f5f8595e62e3bff5ea363f17junov@chromium.org}
94577eec248cbd5a0c2f5f8595e62e3bff5ea363f17junov@chromium.org
9462e14ba8ceb41c68042ff133fecf0561a2c22efcajunov@chromium.orgsize_t SkGPipeCanvas::freeMemoryIfPossible(size_t bytesToFree) {
947d5d158b325f05902ac845f2f7c8c65ffe6074257scroggo@google.com    return (NULL == fBitmapHeap) ? 0 : fBitmapHeap->freeMemoryIfPossible(bytesToFree);
9482e14ba8ceb41c68042ff133fecf0561a2c22efcajunov@chromium.org}
9492e14ba8ceb41c68042ff133fecf0561a2c22efcajunov@chromium.org
950bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com///////////////////////////////////////////////////////////////////////////////
951bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
952bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comtemplate <typename T> uint32_t castToU32(T value) {
953bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    union {
954bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        T           fSrc;
955bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        uint32_t    fDst;
956bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    } data;
957bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    data.fSrc = value;
958bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    return data.fDst;
959bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
960bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
96131891584fef10c88b39f6bf19ac5cde0a862b8c4reed@google.comvoid SkGPipeCanvas::writePaint(const SkPaint& paint) {
962d5d158b325f05902ac845f2f7c8c65ffe6074257scroggo@google.com    if (fDone) {
963d5d158b325f05902ac845f2f7c8c65ffe6074257scroggo@google.com        return;
964d5d158b325f05902ac845f2f7c8c65ffe6074257scroggo@google.com    }
96531891584fef10c88b39f6bf19ac5cde0a862b8c4reed@google.com    SkPaint& base = fPaint;
966bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    uint32_t storage[32];
967bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    uint32_t* ptr = storage;
968bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
969bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (base.getFlags() != paint.getFlags()) {
970bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        *ptr++ = PaintOp_packOpData(kFlags_PaintOp, paint.getFlags());
971f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com        base.setFlags(paint.getFlags());
972bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
973bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (base.getColor() != paint.getColor()) {
974bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        *ptr++ = PaintOp_packOp(kColor_PaintOp);
975bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        *ptr++ = paint.getColor();
976f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com        base.setColor(paint.getColor());
977bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
978bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (base.getStyle() != paint.getStyle()) {
979bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        *ptr++ = PaintOp_packOpData(kStyle_PaintOp, paint.getStyle());
980f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com        base.setStyle(paint.getStyle());
981bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
982bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (base.getStrokeJoin() != paint.getStrokeJoin()) {
983bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        *ptr++ = PaintOp_packOpData(kJoin_PaintOp, paint.getStrokeJoin());
984f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com        base.setStrokeJoin(paint.getStrokeJoin());
985bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
986bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (base.getStrokeCap() != paint.getStrokeCap()) {
987bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        *ptr++ = PaintOp_packOpData(kCap_PaintOp, paint.getStrokeCap());
988f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com        base.setStrokeCap(paint.getStrokeCap());
989bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
990bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (base.getStrokeWidth() != paint.getStrokeWidth()) {
991bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        *ptr++ = PaintOp_packOp(kWidth_PaintOp);
992bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        *ptr++ = castToU32(paint.getStrokeWidth());
993f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com        base.setStrokeWidth(paint.getStrokeWidth());
994bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
995bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (base.getStrokeMiter() != paint.getStrokeMiter()) {
996bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        *ptr++ = PaintOp_packOp(kMiter_PaintOp);
997bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        *ptr++ = castToU32(paint.getStrokeMiter());
998f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com        base.setStrokeMiter(paint.getStrokeMiter());
999bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
1000bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (base.getTextEncoding() != paint.getTextEncoding()) {
1001bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        *ptr++ = PaintOp_packOpData(kEncoding_PaintOp, paint.getTextEncoding());
1002f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com        base.setTextEncoding(paint.getTextEncoding());
1003bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
1004bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (base.getHinting() != paint.getHinting()) {
1005bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        *ptr++ = PaintOp_packOpData(kHinting_PaintOp, paint.getHinting());
1006f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com        base.setHinting(paint.getHinting());
1007bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
1008bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (base.getTextAlign() != paint.getTextAlign()) {
1009bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        *ptr++ = PaintOp_packOpData(kAlign_PaintOp, paint.getTextAlign());
1010f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com        base.setTextAlign(paint.getTextAlign());
1011bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
1012bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (base.getTextSize() != paint.getTextSize()) {
1013bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        *ptr++ = PaintOp_packOp(kTextSize_PaintOp);
1014bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        *ptr++ = castToU32(paint.getTextSize());
1015f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com        base.setTextSize(paint.getTextSize());
1016bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
1017bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (base.getTextScaleX() != paint.getTextScaleX()) {
1018bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        *ptr++ = PaintOp_packOp(kTextScaleX_PaintOp);
1019bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        *ptr++ = castToU32(paint.getTextScaleX());
1020f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com        base.setTextScaleX(paint.getTextScaleX());
1021bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
1022bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (base.getTextSkewX() != paint.getTextSkewX()) {
1023bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        *ptr++ = PaintOp_packOp(kTextSkewX_PaintOp);
1024bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        *ptr++ = castToU32(paint.getTextSkewX());
1025f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com        base.setTextSkewX(paint.getTextSkewX());
1026f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com    }
1027f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com
1028f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com    if (!SkTypeface::Equal(base.getTypeface(), paint.getTypeface())) {
10290c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com        if (isCrossProcess(fFlags)) {
10303cb969f27de56df0d9116c13f18bd31ee0715f1ascroggo@google.com            uint32_t id = this->getTypefaceID(paint.getTypeface());
10313cb969f27de56df0d9116c13f18bd31ee0715f1ascroggo@google.com            *ptr++ = PaintOp_packOpData(kTypeface_PaintOp, id);
10323cb969f27de56df0d9116c13f18bd31ee0715f1ascroggo@google.com        } else if (this->needOpBytes(sizeof(void*))) {
10333cb969f27de56df0d9116c13f18bd31ee0715f1ascroggo@google.com            // Add to the set for ref counting.
10343cb969f27de56df0d9116c13f18bd31ee0715f1ascroggo@google.com            fTypefaceSet.add(paint.getTypeface());
10353cb969f27de56df0d9116c13f18bd31ee0715f1ascroggo@google.com            // It is safe to write the typeface to the stream before the rest
10363cb969f27de56df0d9116c13f18bd31ee0715f1ascroggo@google.com            // of the paint unless we ever send a kReset_PaintOp, which we
10373cb969f27de56df0d9116c13f18bd31ee0715f1ascroggo@google.com            // currently never do.
10383cb969f27de56df0d9116c13f18bd31ee0715f1ascroggo@google.com            this->writeOp(kSetTypeface_DrawOp);
10393cb969f27de56df0d9116c13f18bd31ee0715f1ascroggo@google.com            fWriter.writePtr(paint.getTypeface());
10403cb969f27de56df0d9116c13f18bd31ee0715f1ascroggo@google.com        }
1041f5842f773b7e8612a52784b3c35c7455e67cb90areed@google.com        base.setTypeface(paint.getTypeface());
1042bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
1043bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
10444dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com    // This is a new paint, so all old flats can be safely purged, if necessary.
10454dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com    fFlattenableHeap.markAllFlatsSafeToDelete();
1046b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com    for (int i = 0; i < kCount_PaintFlats; i++) {
1047b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com        int index = this->flattenToIndex(get_paintflat(paint, i), (PaintFlats)i);
1048d3ba5cc85e24896f980ed1ba6e3f4495973baeb3scroggo@google.com        bool replaced = index < 0;
1049d3ba5cc85e24896f980ed1ba6e3f4495973baeb3scroggo@google.com        if (replaced) {
1050d3ba5cc85e24896f980ed1ba6e3f4495973baeb3scroggo@google.com            index = ~index;
1051d3ba5cc85e24896f980ed1ba6e3f4495973baeb3scroggo@google.com        }
10524dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com        // Store the index of any flat that needs to be kept. 0 means no flat.
10534dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com        if (index > 0) {
10544dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com            fFlattenableHeap.markFlatForKeeping(index);
10554dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com        }
10564dffc596aa9fabd3104e66bc1f9957e8de4cb65dscroggo@google.com        SkASSERT(index >= 0 && index <= fFlatDictionary.count());
1057d3ba5cc85e24896f980ed1ba6e3f4495973baeb3scroggo@google.com        if (index != fCurrFlatIndex[i] || replaced) {
1058b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com            *ptr++ = PaintOp_packOpFlagData(kFlatIndex_PaintOp, i, index);
1059b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com            fCurrFlatIndex[i] = index;
1060b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com        }
1061b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com    }
1062b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com
1063acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    size_t size = (char*)ptr - (char*)storage;
1064acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    if (size && this->needOpBytes(size)) {
1065b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com        this->writeOp(kPaintOp_DrawOp, 0, size);
1066b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com        fWriter.write(storage, size);
1067bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        for (size_t i = 0; i < size/4; i++) {
1068b55d118e32062b1ddd88e7fcf8fa86303f887d8freed@google.com//            SkDebugf("[%d] %08X\n", i, storage[i]);
1069bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        }
1070bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
1071bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
1072bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
1073bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com///////////////////////////////////////////////////////////////////////////////
1074bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
1075bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com#include "SkGPipe.h"
1076bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
10773cb969f27de56df0d9116c13f18bd31ee0715f1ascroggo@google.comSkGPipeController::~SkGPipeController() {
10783cb969f27de56df0d9116c13f18bd31ee0715f1ascroggo@google.com    SkSafeUnref(fCanvas);
10793cb969f27de56df0d9116c13f18bd31ee0715f1ascroggo@google.com}
10803cb969f27de56df0d9116c13f18bd31ee0715f1ascroggo@google.com
10813cb969f27de56df0d9116c13f18bd31ee0715f1ascroggo@google.comvoid SkGPipeController::setCanvas(SkGPipeCanvas* canvas) {
10823cb969f27de56df0d9116c13f18bd31ee0715f1ascroggo@google.com    SkRefCnt_SafeAssign(fCanvas, canvas);
10833cb969f27de56df0d9116c13f18bd31ee0715f1ascroggo@google.com}
10843cb969f27de56df0d9116c13f18bd31ee0715f1ascroggo@google.com
10853cb969f27de56df0d9116c13f18bd31ee0715f1ascroggo@google.com///////////////////////////////////////////////////////////////////////////////
10863cb969f27de56df0d9116c13f18bd31ee0715f1ascroggo@google.com
10873cb969f27de56df0d9116c13f18bd31ee0715f1ascroggo@google.comSkGPipeWriter::SkGPipeWriter()
10880c3e5fe728ce4b8606819ee919a4b82f4d9efc85scroggo@google.com: fWriter(0) {
1089bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    fCanvas = NULL;
1090bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
1091bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
1092bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comSkGPipeWriter::~SkGPipeWriter() {
1093acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    this->endRecording();
1094bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
1095bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
1096a8db8fe39a640bda4b85b9342c3b6b2525142afajunov@chromium.orgSkCanvas* SkGPipeWriter::startRecording(SkGPipeController* controller, uint32_t flags,
1097a8db8fe39a640bda4b85b9342c3b6b2525142afajunov@chromium.org                                        uint32_t width, uint32_t height) {
1098bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (NULL == fCanvas) {
1099acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com        fWriter.reset(NULL, 0);
1100a8db8fe39a640bda4b85b9342c3b6b2525142afajunov@chromium.org        fCanvas = SkNEW_ARGS(SkGPipeCanvas, (controller, &fWriter, flags, width, height));
1101bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
11023cb969f27de56df0d9116c13f18bd31ee0715f1ascroggo@google.com    controller->setCanvas(fCanvas);
1103bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    return fCanvas;
1104bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
1105bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
1106bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.comvoid SkGPipeWriter::endRecording() {
1107bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    if (fCanvas) {
1108bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        fCanvas->finish();
1109bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        fCanvas->unref();
1110bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com        fCanvas = NULL;
1111bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com    }
1112bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com}
1113bb6992a9d6e21b3f28068765de0a41c6f2508dfdreed@google.com
11142e14ba8ceb41c68042ff133fecf0561a2c22efcajunov@chromium.orgvoid SkGPipeWriter::flushRecording(bool detachCurrentBlock) {
11152e14ba8ceb41c68042ff133fecf0561a2c22efcajunov@chromium.org    if (fCanvas) {
11162e14ba8ceb41c68042ff133fecf0561a2c22efcajunov@chromium.org        fCanvas->flushRecording(detachCurrentBlock);
11172e14ba8ceb41c68042ff133fecf0561a2c22efcajunov@chromium.org    }
11182e14ba8ceb41c68042ff133fecf0561a2c22efcajunov@chromium.org}
11192e14ba8ceb41c68042ff133fecf0561a2c22efcajunov@chromium.org
11202e14ba8ceb41c68042ff133fecf0561a2c22efcajunov@chromium.orgsize_t SkGPipeWriter::freeMemoryIfPossible(size_t bytesToFree) {
11212e14ba8ceb41c68042ff133fecf0561a2c22efcajunov@chromium.org    if (fCanvas) {
11222e14ba8ceb41c68042ff133fecf0561a2c22efcajunov@chromium.org        return fCanvas->freeMemoryIfPossible(bytesToFree);
11232e14ba8ceb41c68042ff133fecf0561a2c22efcajunov@chromium.org    }
11242e14ba8ceb41c68042ff133fecf0561a2c22efcajunov@chromium.org    return 0;
112577eec248cbd5a0c2f5f8595e62e3bff5ea363f17junov@chromium.org}
112677eec248cbd5a0c2f5f8595e62e3bff5ea363f17junov@chromium.org
11272e14ba8ceb41c68042ff133fecf0561a2c22efcajunov@chromium.orgsize_t SkGPipeWriter::storageAllocatedForRecording() const {
112815011ee5e4068ab6523e432e435473a822ee7d80scroggo@google.com    return NULL == fCanvas ? 0 : fCanvas->storageAllocatedForRecording();
112915011ee5e4068ab6523e432e435473a822ee7d80scroggo@google.com}
113015011ee5e4068ab6523e432e435473a822ee7d80scroggo@google.com
11313e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com///////////////////////////////////////////////////////////////////////////////
11323e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com
11333e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.comBitmapShuttle::BitmapShuttle(SkGPipeCanvas* canvas) {
11343e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com    SkASSERT(canvas != NULL);
11353e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com    fCanvas = canvas;
11363e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com    fCanvas->ref();
11373e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com}
11383e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com
11393e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.comBitmapShuttle::~BitmapShuttle() {
11403e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com    fCanvas->unref();
11413e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com}
11423e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com
11433e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.combool BitmapShuttle::insert(const SkBitmap& bitmap, int32_t slot) {
11443e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com    return fCanvas->shuttleBitmap(bitmap, slot);
11453e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com}
1146