blob: dba178bb84267aa57a672e9ee621c8cdb8b843a8 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
reed@google.combb6992a2011-04-26 17:41:56 +00002/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00003 * Copyright 2011 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
reed@google.combb6992a2011-04-26 17:41:56 +00007 */
8
9
epoger@google.comec3ed6a2011-07-28 14:26:00 +000010
reed@google.combb6992a2011-04-26 17:41:56 +000011#include "SkCanvas.h"
reed@google.com8a85d0c2011-06-24 19:12:12 +000012#include "SkData.h"
reed@google.combb6793b2011-05-05 15:18:15 +000013#include "SkDevice.h"
reed@google.combb6992a2011-04-26 17:41:56 +000014#include "SkPaint.h"
reed@google.comacd471f2011-05-03 21:26:46 +000015#include "SkGPipe.h"
reed@google.combb6992a2011-04-26 17:41:56 +000016#include "SkGPipePriv.h"
reed@google.comf5842f72011-05-04 18:30:04 +000017#include "SkStream.h"
reed@google.comb55d1182011-05-11 00:42:04 +000018#include "SkTSearch.h"
reed@google.comf5842f72011-05-04 18:30:04 +000019#include "SkTypeface.h"
reed@google.combb6992a2011-04-26 17:41:56 +000020#include "SkWriter32.h"
reed@google.comb55d1182011-05-11 00:42:04 +000021#include "SkColorFilter.h"
reed@google.com0faac1e2011-05-11 05:58:58 +000022#include "SkDrawLooper.h"
reed@google.comb55d1182011-05-11 00:42:04 +000023#include "SkMaskFilter.h"
24#include "SkRasterizer.h"
25#include "SkShader.h"
djsollen@google.com2b2ede32012-04-12 13:24:04 +000026#include "SkOrderedWriteBuffer.h"
reed@google.comb55d1182011-05-11 00:42:04 +000027
28static SkFlattenable* get_paintflat(const SkPaint& paint, unsigned paintFlat) {
29 SkASSERT(paintFlat < kCount_PaintFlats);
30 switch (paintFlat) {
31 case kColorFilter_PaintFlat: return paint.getColorFilter();
reed@google.com0faac1e2011-05-11 05:58:58 +000032 case kDrawLooper_PaintFlat: return paint.getLooper();
reed@google.comb55d1182011-05-11 00:42:04 +000033 case kMaskFilter_PaintFlat: return paint.getMaskFilter();
34 case kPathEffect_PaintFlat: return paint.getPathEffect();
35 case kRasterizer_PaintFlat: return paint.getRasterizer();
36 case kShader_PaintFlat: return paint.getShader();
37 case kXfermode_PaintFlat: return paint.getXfermode();
38 }
tomhudson@google.com0c00f212011-12-28 14:59:50 +000039 SkDEBUGFAIL("never gets here");
reed@google.comb55d1182011-05-11 00:42:04 +000040 return NULL;
41}
reed@google.combb6992a2011-04-26 17:41:56 +000042
reed@google.comacd471f2011-05-03 21:26:46 +000043static size_t estimateFlattenSize(const SkPath& path) {
44 int n = path.countPoints();
45 size_t bytes = 3 * sizeof(int32_t);
46 bytes += n * sizeof(SkPoint);
47 bytes += SkAlign4(n + 2); // verbs: add 2 for move/close extras
48
49#ifdef SK_DEBUG
50 {
51 SkWriter32 writer(1024);
52 path.flatten(writer);
53 SkASSERT(writer.size() <= bytes);
54 }
55#endif
56 return bytes;
57}
58
reed@google.comf5842f72011-05-04 18:30:04 +000059static size_t writeTypeface(SkWriter32* writer, SkTypeface* typeface) {
60 SkASSERT(typeface);
61 SkDynamicMemoryWStream stream;
62 typeface->serialize(&stream);
63 size_t size = stream.getOffset();
64 if (writer) {
65 writer->write32(size);
reed@google.com8a85d0c2011-06-24 19:12:12 +000066 SkAutoDataUnref data(stream.copyToData());
67 writer->write(data.data(), size);
reed@google.comf5842f72011-05-04 18:30:04 +000068 }
69 return 4 + size;
70}
71
reed@google.combb6992a2011-04-26 17:41:56 +000072///////////////////////////////////////////////////////////////////////////////
73
74class SkGPipeCanvas : public SkCanvas {
75public:
reed@google.comdde09562011-05-23 12:21:05 +000076 SkGPipeCanvas(SkGPipeController*, SkWriter32*, SkFactorySet*);
reed@google.combb6992a2011-04-26 17:41:56 +000077 virtual ~SkGPipeCanvas();
78
79 void finish() {
80 if (!fDone) {
reed@google.comdbccc882011-07-08 18:53:39 +000081 if (this->needOpBytes()) {
82 this->writeOp(kDone_DrawOp);
83 this->doNotify();
84 }
reed@google.combb6992a2011-04-26 17:41:56 +000085 fDone = true;
86 }
87 }
88
89 // overrides from SkCanvas
scroggo@google.com3b45cd52012-04-18 13:57:47 +000090 virtual int save(SaveFlags) SK_OVERRIDE;
91 virtual int saveLayer(const SkRect* bounds, const SkPaint*,
92 SaveFlags) SK_OVERRIDE;
93 virtual void restore() SK_OVERRIDE;
94 virtual bool translate(SkScalar dx, SkScalar dy) SK_OVERRIDE;
95 virtual bool scale(SkScalar sx, SkScalar sy) SK_OVERRIDE;
96 virtual bool rotate(SkScalar degrees) SK_OVERRIDE;
97 virtual bool skew(SkScalar sx, SkScalar sy) SK_OVERRIDE;
98 virtual bool concat(const SkMatrix& matrix) SK_OVERRIDE;
99 virtual void setMatrix(const SkMatrix& matrix) SK_OVERRIDE;
100 virtual bool clipRect(const SkRect& rect, SkRegion::Op op,
101 bool doAntiAlias = false) SK_OVERRIDE;
102 virtual bool clipPath(const SkPath& path, SkRegion::Op op,
103 bool doAntiAlias = false) SK_OVERRIDE;
104 virtual bool clipRegion(const SkRegion& region, SkRegion::Op op) SK_OVERRIDE;
105 virtual void clear(SkColor) SK_OVERRIDE;
106 virtual void drawPaint(const SkPaint& paint) SK_OVERRIDE;
reed@google.combb6992a2011-04-26 17:41:56 +0000107 virtual void drawPoints(PointMode, size_t count, const SkPoint pts[],
scroggo@google.com3b45cd52012-04-18 13:57:47 +0000108 const SkPaint&) SK_OVERRIDE;
109 virtual void drawRect(const SkRect& rect, const SkPaint&) SK_OVERRIDE;
110 virtual void drawPath(const SkPath& path, const SkPaint&) SK_OVERRIDE;
reed@google.combb6992a2011-04-26 17:41:56 +0000111 virtual void drawBitmap(const SkBitmap&, SkScalar left, SkScalar top,
scroggo@google.com3b45cd52012-04-18 13:57:47 +0000112 const SkPaint*) SK_OVERRIDE;
reed@google.combb6992a2011-04-26 17:41:56 +0000113 virtual void drawBitmapRect(const SkBitmap&, const SkIRect* src,
scroggo@google.com3b45cd52012-04-18 13:57:47 +0000114 const SkRect& dst, const SkPaint*) SK_OVERRIDE;
reed@google.combb6992a2011-04-26 17:41:56 +0000115 virtual void drawBitmapMatrix(const SkBitmap&, const SkMatrix&,
scroggo@google.com3b45cd52012-04-18 13:57:47 +0000116 const SkPaint*) SK_OVERRIDE;
reed@google.combb6992a2011-04-26 17:41:56 +0000117 virtual void drawSprite(const SkBitmap&, int left, int top,
scroggo@google.com3b45cd52012-04-18 13:57:47 +0000118 const SkPaint*) SK_OVERRIDE;
vandebo@chromium.org74b46192012-01-28 01:45:11 +0000119 virtual void drawText(const void* text, size_t byteLength, SkScalar x,
scroggo@google.com3b45cd52012-04-18 13:57:47 +0000120 SkScalar y, const SkPaint&) SK_OVERRIDE;
vandebo@chromium.org74b46192012-01-28 01:45:11 +0000121 virtual void drawPosText(const void* text, size_t byteLength,
scroggo@google.com3b45cd52012-04-18 13:57:47 +0000122 const SkPoint pos[], const SkPaint&) SK_OVERRIDE;
reed@google.combb6992a2011-04-26 17:41:56 +0000123 virtual void drawPosTextH(const void* text, size_t byteLength,
scroggo@google.com3b45cd52012-04-18 13:57:47 +0000124 const SkScalar xpos[], SkScalar constY,
125 const SkPaint&) SK_OVERRIDE;
vandebo@chromium.org74b46192012-01-28 01:45:11 +0000126 virtual void drawTextOnPath(const void* text, size_t byteLength,
127 const SkPath& path, const SkMatrix* matrix,
scroggo@google.com3b45cd52012-04-18 13:57:47 +0000128 const SkPaint&) SK_OVERRIDE;
129 virtual void drawPicture(SkPicture& picture) SK_OVERRIDE;
reed@google.combb6992a2011-04-26 17:41:56 +0000130 virtual void drawVertices(VertexMode, int vertexCount,
131 const SkPoint vertices[], const SkPoint texs[],
132 const SkColor colors[], SkXfermode*,
133 const uint16_t indices[], int indexCount,
scroggo@google.com3b45cd52012-04-18 13:57:47 +0000134 const SkPaint&) SK_OVERRIDE;
135 virtual void drawData(const void*, size_t) SK_OVERRIDE;
reed@google.combb6992a2011-04-26 17:41:56 +0000136
137private:
reed@google.comdde09562011-05-23 12:21:05 +0000138 SkFactorySet* fFactorySet; // optional, only used if cross-process
reed@google.comacd471f2011-05-03 21:26:46 +0000139 SkGPipeController* fController;
reed@google.combb6992a2011-04-26 17:41:56 +0000140 SkWriter32& fWriter;
reed@google.comacd471f2011-05-03 21:26:46 +0000141 size_t fBlockSize; // amount allocated for writer
142 size_t fBytesNotified;
reed@google.combb6992a2011-04-26 17:41:56 +0000143 bool fDone;
144
reed@google.comf5842f72011-05-04 18:30:04 +0000145 SkRefCntSet fTypefaceSet;
146
147 uint32_t getTypefaceID(SkTypeface*);
148
reed@google.comacd471f2011-05-03 21:26:46 +0000149 inline void writeOp(DrawOps op, unsigned flags, unsigned data) {
reed@google.combb6992a2011-04-26 17:41:56 +0000150 fWriter.write32(DrawOp_packOpFlagData(op, flags, data));
151 }
vandebo@chromium.org74b46192012-01-28 01:45:11 +0000152
reed@google.comacd471f2011-05-03 21:26:46 +0000153 inline void writeOp(DrawOps op) {
reed@google.combb6992a2011-04-26 17:41:56 +0000154 fWriter.write32(DrawOp_packOpFlagData(op, 0, 0));
155 }
reed@google.comacd471f2011-05-03 21:26:46 +0000156
157 bool needOpBytes(size_t size = 0);
158
159 inline void doNotify() {
160 if (!fDone) {
161 size_t bytes = fWriter.size() - fBytesNotified;
162 fController->notifyWritten(bytes);
163 fBytesNotified += bytes;
164 }
165 }
reed@google.comb55d1182011-05-11 00:42:04 +0000166
167 struct FlatData {
168 uint32_t fIndex; // always > 0
169 uint32_t fSize;
170
171 void* data() { return (char*)this + sizeof(*this); }
vandebo@chromium.org74b46192012-01-28 01:45:11 +0000172
reed@google.comb55d1182011-05-11 00:42:04 +0000173 static int Compare(const FlatData* a, const FlatData* b) {
174 return memcmp(&a->fSize, &b->fSize, a->fSize + sizeof(a->fSize));
175 }
176 };
177 SkTDArray<FlatData*> fFlatArray;
178 int fCurrFlatIndex[kCount_PaintFlats];
179 int flattenToIndex(SkFlattenable* obj, PaintFlats);
180
reed@google.com31891582011-05-12 03:03:56 +0000181 SkPaint fPaint;
182 void writePaint(const SkPaint&);
reed@google.combb6992a2011-04-26 17:41:56 +0000183
reed@google.comacd471f2011-05-03 21:26:46 +0000184 class AutoPipeNotify {
185 public:
186 AutoPipeNotify(SkGPipeCanvas* canvas) : fCanvas(canvas) {}
187 ~AutoPipeNotify() { fCanvas->doNotify(); }
188 private:
189 SkGPipeCanvas* fCanvas;
190 };
191 friend class AutoPipeNotify;
192
reed@google.combb6992a2011-04-26 17:41:56 +0000193 typedef SkCanvas INHERITED;
194};
195
reed@google.comb55d1182011-05-11 00:42:04 +0000196// return 0 for NULL (or unflattenable obj), or index-base-1
197int SkGPipeCanvas::flattenToIndex(SkFlattenable* obj, PaintFlats paintflat) {
198 if (NULL == obj) {
199 return 0;
200 }
reed@google.comb55d1182011-05-11 00:42:04 +0000201
djsollen@google.com2b2ede32012-04-12 13:24:04 +0000202 SkOrderedWriteBuffer tmpWriter(1024);
reed@google.com6bac9472011-06-21 19:24:00 +0000203 tmpWriter.setFlags(SkFlattenableWriteBuffer::kInlineFactoryNames_Flag);
reed@google.comdde09562011-05-23 12:21:05 +0000204 tmpWriter.setFactoryRecorder(fFactorySet);
205
reed@google.comb55d1182011-05-11 00:42:04 +0000206 tmpWriter.writeFlattenable(obj);
207 size_t len = tmpWriter.size();
208 size_t allocSize = len + sizeof(FlatData);
209
210 SkAutoSMalloc<1024> storage(allocSize);
211 FlatData* flat = (FlatData*)storage.get();
212 flat->fSize = len;
213 tmpWriter.flatten(flat->data());
214
215 int index = SkTSearch<FlatData>((const FlatData**)fFlatArray.begin(),
216 fFlatArray.count(), flat, sizeof(flat),
217 &FlatData::Compare);
218 if (index < 0) {
219 index = ~index;
220 FlatData* copy = (FlatData*)sk_malloc_throw(allocSize);
221 memcpy(copy, flat, allocSize);
222 *fFlatArray.insert(index) = copy;
223 // call this after the insert, so that count() will have been grown
224 copy->fIndex = fFlatArray.count();
225// SkDebugf("--- add flattenable[%d] size=%d index=%d\n", paintflat, len, copy->fIndex);
226
227 if (this->needOpBytes(len)) {
reed@google.com0faac1e2011-05-11 05:58:58 +0000228 this->writeOp(kDef_Flattenable_DrawOp, paintflat, copy->fIndex);
reed@google.comb55d1182011-05-11 00:42:04 +0000229 fWriter.write(copy->data(), len);
230 }
231 }
232 return fFlatArray[index]->fIndex;
233}
234
reed@google.combb6992a2011-04-26 17:41:56 +0000235///////////////////////////////////////////////////////////////////////////////
236
reed@google.comacd471f2011-05-03 21:26:46 +0000237#define MIN_BLOCK_SIZE (16 * 1024)
reed@google.combb6992a2011-04-26 17:41:56 +0000238
reed@google.comacd471f2011-05-03 21:26:46 +0000239SkGPipeCanvas::SkGPipeCanvas(SkGPipeController* controller,
reed@google.comdde09562011-05-23 12:21:05 +0000240 SkWriter32* writer, SkFactorySet* fset)
reed@google.com67908f22011-06-27 14:47:50 +0000241 : fWriter(*writer) {
242 fFactorySet = fset;
reed@google.comacd471f2011-05-03 21:26:46 +0000243 fController = controller;
reed@google.combb6992a2011-04-26 17:41:56 +0000244 fDone = false;
reed@google.comacd471f2011-05-03 21:26:46 +0000245 fBlockSize = 0; // need first block from controller
reed@google.comb55d1182011-05-11 00:42:04 +0000246 sk_bzero(fCurrFlatIndex, sizeof(fCurrFlatIndex));
reed@google.comacd471f2011-05-03 21:26:46 +0000247
reed@google.combb6793b2011-05-05 15:18:15 +0000248 // we need a device to limit our clip
249 // should the caller give us the bounds?
yangsu@google.com06b4da162011-06-17 15:04:40 +0000250 // We don't allocate pixels for the bitmap
reed@google.combb6793b2011-05-05 15:18:15 +0000251 SkBitmap bitmap;
252 bitmap.setConfig(SkBitmap::kARGB_8888_Config, 32767, 32767);
yangsu@google.com06b4da162011-06-17 15:04:40 +0000253 SkDevice* device = SkNEW_ARGS(SkDevice, (bitmap));
reed@google.combb6793b2011-05-05 15:18:15 +0000254 this->setDevice(device)->unref();
reed@google.combb6992a2011-04-26 17:41:56 +0000255}
256
257SkGPipeCanvas::~SkGPipeCanvas() {
258 this->finish();
259
reed@google.comb55d1182011-05-11 00:42:04 +0000260 fFlatArray.freeAll();
reed@google.combb6992a2011-04-26 17:41:56 +0000261}
262
reed@google.comacd471f2011-05-03 21:26:46 +0000263bool SkGPipeCanvas::needOpBytes(size_t needed) {
264 if (fDone) {
265 return false;
266 }
267
268 needed += 4; // size of DrawOp atom
269 if (fWriter.size() + needed > fBlockSize) {
270 void* block = fController->requestBlock(MIN_BLOCK_SIZE, &fBlockSize);
271 if (NULL == block) {
272 fDone = true;
273 return false;
274 }
275 fWriter.reset(block, fBlockSize);
276 fBytesNotified = 0;
277 }
278 return true;
279}
280
reed@google.comf5842f72011-05-04 18:30:04 +0000281uint32_t SkGPipeCanvas::getTypefaceID(SkTypeface* face) {
282 uint32_t id = 0; // 0 means default/null typeface
283 if (face) {
284 id = fTypefaceSet.find(face);
285 if (0 == id) {
286 id = fTypefaceSet.add(face);
287 size_t size = writeTypeface(NULL, face);
288 if (this->needOpBytes(size)) {
reed@google.combb6793b2011-05-05 15:18:15 +0000289 this->writeOp(kDef_Typeface_DrawOp);
reed@google.comf5842f72011-05-04 18:30:04 +0000290 writeTypeface(&fWriter, face);
291 }
292 }
293 }
294 return id;
295}
296
reed@google.combb6992a2011-04-26 17:41:56 +0000297///////////////////////////////////////////////////////////////////////////////
298
reed@google.comacd471f2011-05-03 21:26:46 +0000299#define NOTIFY_SETUP(canvas) \
300 AutoPipeNotify apn(canvas)
301
reed@google.combb6992a2011-04-26 17:41:56 +0000302int SkGPipeCanvas::save(SaveFlags flags) {
reed@google.comacd471f2011-05-03 21:26:46 +0000303 NOTIFY_SETUP(this);
304 if (this->needOpBytes()) {
305 this->writeOp(kSave_DrawOp, 0, flags);
306 }
reed@google.combb6992a2011-04-26 17:41:56 +0000307 return this->INHERITED::save(flags);
308}
309
310int SkGPipeCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint,
311 SaveFlags saveFlags) {
reed@google.comacd471f2011-05-03 21:26:46 +0000312 NOTIFY_SETUP(this);
313 size_t size = 0;
reed@google.combb6992a2011-04-26 17:41:56 +0000314 unsigned opFlags = 0;
vandebo@chromium.org74b46192012-01-28 01:45:11 +0000315
reed@google.combb6992a2011-04-26 17:41:56 +0000316 if (bounds) {
317 opFlags |= kSaveLayer_HasBounds_DrawOpFlag;
reed@google.comacd471f2011-05-03 21:26:46 +0000318 size += sizeof(SkRect);
reed@google.combb6992a2011-04-26 17:41:56 +0000319 }
320 if (paint) {
321 opFlags |= kSaveLayer_HasPaint_DrawOpFlag;
reed@google.com31891582011-05-12 03:03:56 +0000322 this->writePaint(*paint);
reed@google.combb6992a2011-04-26 17:41:56 +0000323 }
324
reed@google.comacd471f2011-05-03 21:26:46 +0000325 if (this->needOpBytes(size)) {
326 this->writeOp(kSaveLayer_DrawOp, opFlags, saveFlags);
327 if (bounds) {
328 fWriter.writeRect(*bounds);
329 }
reed@google.combb6992a2011-04-26 17:41:56 +0000330 }
vandebo@chromium.org74b46192012-01-28 01:45:11 +0000331
reed@google.combb6992a2011-04-26 17:41:56 +0000332 // we just pass on the save, so we don't create a layer
333 return this->INHERITED::save(saveFlags);
334}
335
336void SkGPipeCanvas::restore() {
reed@google.comacd471f2011-05-03 21:26:46 +0000337 NOTIFY_SETUP(this);
338 if (this->needOpBytes()) {
339 this->writeOp(kRestore_DrawOp);
340 }
reed@google.combb6992a2011-04-26 17:41:56 +0000341 this->INHERITED::restore();
342}
343
344bool SkGPipeCanvas::translate(SkScalar dx, SkScalar dy) {
345 if (dx || dy) {
reed@google.comacd471f2011-05-03 21:26:46 +0000346 NOTIFY_SETUP(this);
347 if (this->needOpBytes(2 * sizeof(SkScalar))) {
348 this->writeOp(kTranslate_DrawOp);
349 fWriter.writeScalar(dx);
350 fWriter.writeScalar(dy);
351 }
reed@google.combb6992a2011-04-26 17:41:56 +0000352 }
353 return this->INHERITED::translate(dx, dy);
354}
355
356bool SkGPipeCanvas::scale(SkScalar sx, SkScalar sy) {
357 if (sx || sy) {
reed@google.comacd471f2011-05-03 21:26:46 +0000358 NOTIFY_SETUP(this);
359 if (this->needOpBytes(2 * sizeof(SkScalar))) {
360 this->writeOp(kScale_DrawOp);
361 fWriter.writeScalar(sx);
362 fWriter.writeScalar(sy);
363 }
reed@google.combb6992a2011-04-26 17:41:56 +0000364 }
365 return this->INHERITED::scale(sx, sy);
366}
367
368bool SkGPipeCanvas::rotate(SkScalar degrees) {
369 if (degrees) {
reed@google.comacd471f2011-05-03 21:26:46 +0000370 NOTIFY_SETUP(this);
371 if (this->needOpBytes(sizeof(SkScalar))) {
372 this->writeOp(kRotate_DrawOp);
373 fWriter.writeScalar(degrees);
374 }
reed@google.combb6992a2011-04-26 17:41:56 +0000375 }
376 return this->INHERITED::rotate(degrees);
377}
378
379bool SkGPipeCanvas::skew(SkScalar sx, SkScalar sy) {
380 if (sx || sy) {
reed@google.comacd471f2011-05-03 21:26:46 +0000381 NOTIFY_SETUP(this);
382 if (this->needOpBytes(2 * sizeof(SkScalar))) {
383 this->writeOp(kSkew_DrawOp);
384 fWriter.writeScalar(sx);
385 fWriter.writeScalar(sy);
386 }
reed@google.combb6992a2011-04-26 17:41:56 +0000387 }
388 return this->INHERITED::skew(sx, sy);
389}
390
391bool SkGPipeCanvas::concat(const SkMatrix& matrix) {
392 if (!matrix.isIdentity()) {
reed@google.comacd471f2011-05-03 21:26:46 +0000393 NOTIFY_SETUP(this);
394 if (this->needOpBytes(matrix.flatten(NULL))) {
395 this->writeOp(kConcat_DrawOp);
djsollen@google.com2b2ede32012-04-12 13:24:04 +0000396 fWriter.writeMatrix(matrix);
reed@google.comacd471f2011-05-03 21:26:46 +0000397 }
reed@google.combb6992a2011-04-26 17:41:56 +0000398 }
399 return this->INHERITED::concat(matrix);
400}
401
402void SkGPipeCanvas::setMatrix(const SkMatrix& matrix) {
reed@google.comacd471f2011-05-03 21:26:46 +0000403 NOTIFY_SETUP(this);
404 if (this->needOpBytes(matrix.flatten(NULL))) {
405 this->writeOp(kSetMatrix_DrawOp);
djsollen@google.com2b2ede32012-04-12 13:24:04 +0000406 fWriter.writeMatrix(matrix);
reed@google.comacd471f2011-05-03 21:26:46 +0000407 }
reed@google.combb6992a2011-04-26 17:41:56 +0000408 this->INHERITED::setMatrix(matrix);
409}
410
scroggo@google.com3b45cd52012-04-18 13:57:47 +0000411bool SkGPipeCanvas::clipRect(const SkRect& rect, SkRegion::Op rgnOp,
412 bool doAntiAlias) {
reed@google.comacd471f2011-05-03 21:26:46 +0000413 NOTIFY_SETUP(this);
scroggo@google.com3b45cd52012-04-18 13:57:47 +0000414 if (this->needOpBytes(sizeof(SkRect)) + sizeof(bool)) {
reed@google.comacd471f2011-05-03 21:26:46 +0000415 this->writeOp(kClipRect_DrawOp, 0, rgnOp);
416 fWriter.writeRect(rect);
scroggo@google.com3b45cd52012-04-18 13:57:47 +0000417 fWriter.writeBool(doAntiAlias);
reed@google.comacd471f2011-05-03 21:26:46 +0000418 }
scroggo@google.com3b45cd52012-04-18 13:57:47 +0000419 return this->INHERITED::clipRect(rect, rgnOp, doAntiAlias);
reed@google.combb6992a2011-04-26 17:41:56 +0000420}
421
scroggo@google.com3b45cd52012-04-18 13:57:47 +0000422bool SkGPipeCanvas::clipPath(const SkPath& path, SkRegion::Op rgnOp,
423 bool doAntiAlias) {
reed@google.comacd471f2011-05-03 21:26:46 +0000424 NOTIFY_SETUP(this);
scroggo@google.com3b45cd52012-04-18 13:57:47 +0000425 if (this->needOpBytes(estimateFlattenSize(path)) + sizeof(bool)) {
reed@google.comacd471f2011-05-03 21:26:46 +0000426 this->writeOp(kClipPath_DrawOp, 0, rgnOp);
427 path.flatten(fWriter);
scroggo@google.com3b45cd52012-04-18 13:57:47 +0000428 fWriter.writeBool(doAntiAlias);
reed@google.comacd471f2011-05-03 21:26:46 +0000429 }
reed@google.combb6992a2011-04-26 17:41:56 +0000430 // we just pass on the bounds of the path
scroggo@google.com3b45cd52012-04-18 13:57:47 +0000431 return this->INHERITED::clipRect(path.getBounds(), rgnOp, doAntiAlias);
reed@google.combb6992a2011-04-26 17:41:56 +0000432}
433
434bool SkGPipeCanvas::clipRegion(const SkRegion& region, SkRegion::Op rgnOp) {
reed@google.comacd471f2011-05-03 21:26:46 +0000435 NOTIFY_SETUP(this);
436 if (this->needOpBytes(region.flatten(NULL))) {
437 this->writeOp(kClipRegion_DrawOp, 0, rgnOp);
djsollen@google.com2b2ede32012-04-12 13:24:04 +0000438 fWriter.writeRegion(region);
reed@google.comacd471f2011-05-03 21:26:46 +0000439 }
reed@google.combb6992a2011-04-26 17:41:56 +0000440 return this->INHERITED::clipRegion(region, rgnOp);
441}
442
443///////////////////////////////////////////////////////////////////////////////
444
445void SkGPipeCanvas::clear(SkColor color) {
reed@google.comacd471f2011-05-03 21:26:46 +0000446 NOTIFY_SETUP(this);
reed@google.combb6992a2011-04-26 17:41:56 +0000447 unsigned flags = 0;
448 if (color) {
449 flags |= kClear_HasColor_DrawOpFlag;
450 }
reed@google.comacd471f2011-05-03 21:26:46 +0000451 if (this->needOpBytes(sizeof(SkColor))) {
452 this->writeOp(kDrawClear_DrawOp, flags, 0);
453 if (color) {
454 fWriter.write32(color);
455 }
reed@google.combb6992a2011-04-26 17:41:56 +0000456 }
457}
458
459void SkGPipeCanvas::drawPaint(const SkPaint& paint) {
reed@google.comacd471f2011-05-03 21:26:46 +0000460 NOTIFY_SETUP(this);
reed@google.com31891582011-05-12 03:03:56 +0000461 this->writePaint(paint);
reed@google.comacd471f2011-05-03 21:26:46 +0000462 if (this->needOpBytes()) {
reed@google.com31891582011-05-12 03:03:56 +0000463 this->writeOp(kDrawPaint_DrawOp);
reed@google.comacd471f2011-05-03 21:26:46 +0000464 }
reed@google.combb6992a2011-04-26 17:41:56 +0000465}
466
467void SkGPipeCanvas::drawPoints(PointMode mode, size_t count,
468 const SkPoint pts[], const SkPaint& paint) {
469 if (count) {
reed@google.comacd471f2011-05-03 21:26:46 +0000470 NOTIFY_SETUP(this);
reed@google.com31891582011-05-12 03:03:56 +0000471 this->writePaint(paint);
reed@google.comacd471f2011-05-03 21:26:46 +0000472 if (this->needOpBytes(4 + count * sizeof(SkPoint))) {
reed@google.com31891582011-05-12 03:03:56 +0000473 this->writeOp(kDrawPoints_DrawOp, mode, 0);
reed@google.comacd471f2011-05-03 21:26:46 +0000474 fWriter.write32(count);
475 fWriter.write(pts, count * sizeof(SkPoint));
476 }
reed@google.combb6992a2011-04-26 17:41:56 +0000477 }
478}
479
480void SkGPipeCanvas::drawRect(const SkRect& rect, const SkPaint& paint) {
reed@google.comacd471f2011-05-03 21:26:46 +0000481 NOTIFY_SETUP(this);
reed@google.com31891582011-05-12 03:03:56 +0000482 this->writePaint(paint);
reed@google.comacd471f2011-05-03 21:26:46 +0000483 if (this->needOpBytes(sizeof(SkRect))) {
reed@google.com31891582011-05-12 03:03:56 +0000484 this->writeOp(kDrawRect_DrawOp);
reed@google.comacd471f2011-05-03 21:26:46 +0000485 fWriter.writeRect(rect);
486 }
reed@google.combb6992a2011-04-26 17:41:56 +0000487}
488
489void SkGPipeCanvas::drawPath(const SkPath& path, const SkPaint& paint) {
reed@google.comacd471f2011-05-03 21:26:46 +0000490 NOTIFY_SETUP(this);
reed@google.com31891582011-05-12 03:03:56 +0000491 this->writePaint(paint);
reed@google.comacd471f2011-05-03 21:26:46 +0000492 if (this->needOpBytes(estimateFlattenSize(path))) {
reed@google.com31891582011-05-12 03:03:56 +0000493 this->writeOp(kDrawPath_DrawOp);
reed@google.comacd471f2011-05-03 21:26:46 +0000494 path.flatten(fWriter);
495 }
reed@google.combb6992a2011-04-26 17:41:56 +0000496}
497
498void SkGPipeCanvas::drawBitmap(const SkBitmap&, SkScalar left, SkScalar top,
499 const SkPaint*) {
500 UNIMPLEMENTED
501}
502
503void SkGPipeCanvas::drawBitmapRect(const SkBitmap&, const SkIRect* src,
504 const SkRect& dst, const SkPaint*) {
505 UNIMPLEMENTED
506}
507
508void SkGPipeCanvas::drawBitmapMatrix(const SkBitmap&, const SkMatrix&,
509 const SkPaint*) {
510 UNIMPLEMENTED
511}
512
513void SkGPipeCanvas::drawSprite(const SkBitmap&, int left, int top,
514 const SkPaint*) {
515 UNIMPLEMENTED
516}
517
vandebo@chromium.org74b46192012-01-28 01:45:11 +0000518void SkGPipeCanvas::drawText(const void* text, size_t byteLength, SkScalar x,
reed@google.combb6992a2011-04-26 17:41:56 +0000519 SkScalar y, const SkPaint& paint) {
520 if (byteLength) {
reed@google.comacd471f2011-05-03 21:26:46 +0000521 NOTIFY_SETUP(this);
reed@google.com31891582011-05-12 03:03:56 +0000522 this->writePaint(paint);
reed@google.comacd471f2011-05-03 21:26:46 +0000523 if (this->needOpBytes(4 + SkAlign4(byteLength) + 2 * sizeof(SkScalar))) {
reed@google.com31891582011-05-12 03:03:56 +0000524 this->writeOp(kDrawText_DrawOp);
reed@google.comacd471f2011-05-03 21:26:46 +0000525 fWriter.write32(byteLength);
526 fWriter.writePad(text, byteLength);
527 fWriter.writeScalar(x);
528 fWriter.writeScalar(y);
529 }
reed@google.combb6992a2011-04-26 17:41:56 +0000530 }
531}
532
vandebo@chromium.org74b46192012-01-28 01:45:11 +0000533void SkGPipeCanvas::drawPosText(const void* text, size_t byteLength,
reed@google.combb6992a2011-04-26 17:41:56 +0000534 const SkPoint pos[], const SkPaint& paint) {
535 if (byteLength) {
reed@google.comacd471f2011-05-03 21:26:46 +0000536 NOTIFY_SETUP(this);
reed@google.com31891582011-05-12 03:03:56 +0000537 this->writePaint(paint);
reed@google.combb6992a2011-04-26 17:41:56 +0000538 int count = paint.textToGlyphs(text, byteLength, NULL);
reed@google.comacd471f2011-05-03 21:26:46 +0000539 if (this->needOpBytes(4 + SkAlign4(byteLength) + 4 + count * sizeof(SkPoint))) {
reed@google.com31891582011-05-12 03:03:56 +0000540 this->writeOp(kDrawPosText_DrawOp);
reed@google.comacd471f2011-05-03 21:26:46 +0000541 fWriter.write32(byteLength);
542 fWriter.writePad(text, byteLength);
543 fWriter.write32(count);
544 fWriter.write(pos, count * sizeof(SkPoint));
545 }
reed@google.combb6992a2011-04-26 17:41:56 +0000546 }
547}
548
549void SkGPipeCanvas::drawPosTextH(const void* text, size_t byteLength,
550 const SkScalar xpos[], SkScalar constY,
551 const SkPaint& paint) {
552 if (byteLength) {
reed@google.comacd471f2011-05-03 21:26:46 +0000553 NOTIFY_SETUP(this);
reed@google.com31891582011-05-12 03:03:56 +0000554 this->writePaint(paint);
reed@google.combb6992a2011-04-26 17:41:56 +0000555 int count = paint.textToGlyphs(text, byteLength, NULL);
reed@google.comacd471f2011-05-03 21:26:46 +0000556 if (this->needOpBytes(4 + SkAlign4(byteLength) + 4 + count * sizeof(SkScalar) + 4)) {
reed@google.com31891582011-05-12 03:03:56 +0000557 this->writeOp(kDrawPosTextH_DrawOp);
reed@google.comacd471f2011-05-03 21:26:46 +0000558 fWriter.write32(byteLength);
559 fWriter.writePad(text, byteLength);
560 fWriter.write32(count);
561 fWriter.write(xpos, count * sizeof(SkScalar));
562 fWriter.writeScalar(constY);
563 }
reed@google.combb6992a2011-04-26 17:41:56 +0000564 }
565}
566
vandebo@chromium.org74b46192012-01-28 01:45:11 +0000567void SkGPipeCanvas::drawTextOnPath(const void* text, size_t byteLength,
568 const SkPath& path, const SkMatrix* matrix,
reed@google.combb6992a2011-04-26 17:41:56 +0000569 const SkPaint& paint) {
570 if (byteLength) {
reed@google.comacd471f2011-05-03 21:26:46 +0000571 NOTIFY_SETUP(this);
reed@google.combb6992a2011-04-26 17:41:56 +0000572 unsigned flags = 0;
reed@google.comacd471f2011-05-03 21:26:46 +0000573 size_t size = 4 + SkAlign4(byteLength) + estimateFlattenSize(path);
reed@google.combb6992a2011-04-26 17:41:56 +0000574 if (matrix) {
575 flags |= kDrawTextOnPath_HasMatrix_DrawOpFlag;
reed@google.comacd471f2011-05-03 21:26:46 +0000576 size += matrix->flatten(NULL);
reed@google.combb6992a2011-04-26 17:41:56 +0000577 }
reed@google.com31891582011-05-12 03:03:56 +0000578 this->writePaint(paint);
reed@google.comacd471f2011-05-03 21:26:46 +0000579 if (this->needOpBytes(size)) {
reed@google.com31891582011-05-12 03:03:56 +0000580 this->writeOp(kDrawTextOnPath_DrawOp, flags, 0);
reed@google.combb6992a2011-04-26 17:41:56 +0000581
reed@google.comacd471f2011-05-03 21:26:46 +0000582 fWriter.write32(byteLength);
583 fWriter.writePad(text, byteLength);
reed@google.combb6992a2011-04-26 17:41:56 +0000584
reed@google.comacd471f2011-05-03 21:26:46 +0000585 path.flatten(fWriter);
586 if (matrix) {
djsollen@google.com2b2ede32012-04-12 13:24:04 +0000587 fWriter.writeMatrix(*matrix);
reed@google.comacd471f2011-05-03 21:26:46 +0000588 }
reed@google.combb6992a2011-04-26 17:41:56 +0000589 }
590 }
591}
592
593void SkGPipeCanvas::drawPicture(SkPicture& picture) {
reed@google.com0faac1e2011-05-11 05:58:58 +0000594 // we want to playback the picture into individual draw calls
595 this->INHERITED::drawPicture(picture);
reed@google.combb6992a2011-04-26 17:41:56 +0000596}
597
reed@google.combb6992a2011-04-26 17:41:56 +0000598void SkGPipeCanvas::drawVertices(VertexMode mode, int vertexCount,
599 const SkPoint vertices[], const SkPoint texs[],
600 const SkColor colors[], SkXfermode*,
601 const uint16_t indices[], int indexCount,
602 const SkPaint& paint) {
603 if (0 == vertexCount) {
604 return;
605 }
606
reed@google.comacd471f2011-05-03 21:26:46 +0000607 NOTIFY_SETUP(this);
608 size_t size = 4 + vertexCount * sizeof(SkPoint);
reed@google.com31891582011-05-12 03:03:56 +0000609 this->writePaint(paint);
reed@google.combb6992a2011-04-26 17:41:56 +0000610 unsigned flags = 0;
611 if (texs) {
612 flags |= kDrawVertices_HasTexs_DrawOpFlag;
reed@google.comacd471f2011-05-03 21:26:46 +0000613 size += vertexCount * sizeof(SkPoint);
reed@google.combb6992a2011-04-26 17:41:56 +0000614 }
615 if (colors) {
616 flags |= kDrawVertices_HasColors_DrawOpFlag;
reed@google.comacd471f2011-05-03 21:26:46 +0000617 size += vertexCount * sizeof(SkColor);
reed@google.combb6992a2011-04-26 17:41:56 +0000618 }
619 if (indices && indexCount > 0) {
620 flags |= kDrawVertices_HasIndices_DrawOpFlag;
reed@google.comacd471f2011-05-03 21:26:46 +0000621 size += 4 + SkAlign4(indexCount * sizeof(uint16_t));
reed@google.combb6992a2011-04-26 17:41:56 +0000622 }
vandebo@chromium.org74b46192012-01-28 01:45:11 +0000623
reed@google.comacd471f2011-05-03 21:26:46 +0000624 if (this->needOpBytes(size)) {
reed@google.com31891582011-05-12 03:03:56 +0000625 this->writeOp(kDrawVertices_DrawOp, flags, 0);
reed@google.comacd471f2011-05-03 21:26:46 +0000626 fWriter.write32(mode);
627 fWriter.write32(vertexCount);
628 fWriter.write(vertices, vertexCount * sizeof(SkPoint));
629 if (texs) {
630 fWriter.write(texs, vertexCount * sizeof(SkPoint));
631 }
632 if (colors) {
633 fWriter.write(colors, vertexCount * sizeof(SkColor));
634 }
reed@google.combb6992a2011-04-26 17:41:56 +0000635
reed@google.comacd471f2011-05-03 21:26:46 +0000636 // TODO: flatten xfermode
reed@google.combb6992a2011-04-26 17:41:56 +0000637
reed@google.comacd471f2011-05-03 21:26:46 +0000638 if (indices && indexCount > 0) {
639 fWriter.write32(indexCount);
640 fWriter.writePad(indices, indexCount * sizeof(uint16_t));
641 }
reed@google.combb6992a2011-04-26 17:41:56 +0000642 }
643}
644
reed@google.comacd471f2011-05-03 21:26:46 +0000645void SkGPipeCanvas::drawData(const void* ptr, size_t size) {
646 if (size && ptr) {
647 NOTIFY_SETUP(this);
reed@google.combb6992a2011-04-26 17:41:56 +0000648 unsigned data = 0;
649 if (size < (1 << DRAWOPS_DATA_BITS)) {
650 data = (unsigned)size;
651 }
reed@google.comacd471f2011-05-03 21:26:46 +0000652 if (this->needOpBytes(4 + SkAlign4(size))) {
653 this->writeOp(kDrawData_DrawOp, 0, data);
654 if (0 == data) {
655 fWriter.write32(size);
656 }
reed@google.combb6793b2011-05-05 15:18:15 +0000657 fWriter.writePad(ptr, size);
reed@google.combb6992a2011-04-26 17:41:56 +0000658 }
659 }
660}
661
662///////////////////////////////////////////////////////////////////////////////
663
664template <typename T> uint32_t castToU32(T value) {
665 union {
666 T fSrc;
667 uint32_t fDst;
668 } data;
669 data.fSrc = value;
670 return data.fDst;
671}
672
reed@google.com31891582011-05-12 03:03:56 +0000673void SkGPipeCanvas::writePaint(const SkPaint& paint) {
674 SkPaint& base = fPaint;
reed@google.combb6992a2011-04-26 17:41:56 +0000675 uint32_t storage[32];
676 uint32_t* ptr = storage;
reed@google.combb6992a2011-04-26 17:41:56 +0000677
678 if (base.getFlags() != paint.getFlags()) {
reed@google.combb6992a2011-04-26 17:41:56 +0000679 *ptr++ = PaintOp_packOpData(kFlags_PaintOp, paint.getFlags());
reed@google.comf5842f72011-05-04 18:30:04 +0000680 base.setFlags(paint.getFlags());
reed@google.combb6992a2011-04-26 17:41:56 +0000681 }
682 if (base.getColor() != paint.getColor()) {
reed@google.combb6992a2011-04-26 17:41:56 +0000683 *ptr++ = PaintOp_packOp(kColor_PaintOp);
684 *ptr++ = paint.getColor();
reed@google.comf5842f72011-05-04 18:30:04 +0000685 base.setColor(paint.getColor());
reed@google.combb6992a2011-04-26 17:41:56 +0000686 }
687 if (base.getStyle() != paint.getStyle()) {
reed@google.combb6992a2011-04-26 17:41:56 +0000688 *ptr++ = PaintOp_packOpData(kStyle_PaintOp, paint.getStyle());
reed@google.comf5842f72011-05-04 18:30:04 +0000689 base.setStyle(paint.getStyle());
reed@google.combb6992a2011-04-26 17:41:56 +0000690 }
691 if (base.getStrokeJoin() != paint.getStrokeJoin()) {
reed@google.combb6992a2011-04-26 17:41:56 +0000692 *ptr++ = PaintOp_packOpData(kJoin_PaintOp, paint.getStrokeJoin());
reed@google.comf5842f72011-05-04 18:30:04 +0000693 base.setStrokeJoin(paint.getStrokeJoin());
reed@google.combb6992a2011-04-26 17:41:56 +0000694 }
695 if (base.getStrokeCap() != paint.getStrokeCap()) {
reed@google.combb6992a2011-04-26 17:41:56 +0000696 *ptr++ = PaintOp_packOpData(kCap_PaintOp, paint.getStrokeCap());
reed@google.comf5842f72011-05-04 18:30:04 +0000697 base.setStrokeCap(paint.getStrokeCap());
reed@google.combb6992a2011-04-26 17:41:56 +0000698 }
699 if (base.getStrokeWidth() != paint.getStrokeWidth()) {
reed@google.combb6992a2011-04-26 17:41:56 +0000700 *ptr++ = PaintOp_packOp(kWidth_PaintOp);
701 *ptr++ = castToU32(paint.getStrokeWidth());
reed@google.comf5842f72011-05-04 18:30:04 +0000702 base.setStrokeWidth(paint.getStrokeWidth());
reed@google.combb6992a2011-04-26 17:41:56 +0000703 }
704 if (base.getStrokeMiter() != paint.getStrokeMiter()) {
reed@google.combb6992a2011-04-26 17:41:56 +0000705 *ptr++ = PaintOp_packOp(kMiter_PaintOp);
706 *ptr++ = castToU32(paint.getStrokeMiter());
reed@google.comf5842f72011-05-04 18:30:04 +0000707 base.setStrokeMiter(paint.getStrokeMiter());
reed@google.combb6992a2011-04-26 17:41:56 +0000708 }
709 if (base.getTextEncoding() != paint.getTextEncoding()) {
reed@google.combb6992a2011-04-26 17:41:56 +0000710 *ptr++ = PaintOp_packOpData(kEncoding_PaintOp, paint.getTextEncoding());
reed@google.comf5842f72011-05-04 18:30:04 +0000711 base.setTextEncoding(paint.getTextEncoding());
reed@google.combb6992a2011-04-26 17:41:56 +0000712 }
713 if (base.getHinting() != paint.getHinting()) {
reed@google.combb6992a2011-04-26 17:41:56 +0000714 *ptr++ = PaintOp_packOpData(kHinting_PaintOp, paint.getHinting());
reed@google.comf5842f72011-05-04 18:30:04 +0000715 base.setHinting(paint.getHinting());
reed@google.combb6992a2011-04-26 17:41:56 +0000716 }
717 if (base.getTextAlign() != paint.getTextAlign()) {
reed@google.combb6992a2011-04-26 17:41:56 +0000718 *ptr++ = PaintOp_packOpData(kAlign_PaintOp, paint.getTextAlign());
reed@google.comf5842f72011-05-04 18:30:04 +0000719 base.setTextAlign(paint.getTextAlign());
reed@google.combb6992a2011-04-26 17:41:56 +0000720 }
721 if (base.getTextSize() != paint.getTextSize()) {
reed@google.combb6992a2011-04-26 17:41:56 +0000722 *ptr++ = PaintOp_packOp(kTextSize_PaintOp);
723 *ptr++ = castToU32(paint.getTextSize());
reed@google.comf5842f72011-05-04 18:30:04 +0000724 base.setTextSize(paint.getTextSize());
reed@google.combb6992a2011-04-26 17:41:56 +0000725 }
726 if (base.getTextScaleX() != paint.getTextScaleX()) {
reed@google.combb6992a2011-04-26 17:41:56 +0000727 *ptr++ = PaintOp_packOp(kTextScaleX_PaintOp);
728 *ptr++ = castToU32(paint.getTextScaleX());
reed@google.comf5842f72011-05-04 18:30:04 +0000729 base.setTextScaleX(paint.getTextScaleX());
reed@google.combb6992a2011-04-26 17:41:56 +0000730 }
731 if (base.getTextSkewX() != paint.getTextSkewX()) {
reed@google.combb6992a2011-04-26 17:41:56 +0000732 *ptr++ = PaintOp_packOp(kTextSkewX_PaintOp);
733 *ptr++ = castToU32(paint.getTextSkewX());
reed@google.comf5842f72011-05-04 18:30:04 +0000734 base.setTextSkewX(paint.getTextSkewX());
735 }
736
737 if (!SkTypeface::Equal(base.getTypeface(), paint.getTypeface())) {
738 uint32_t id = this->getTypefaceID(paint.getTypeface());
reed@google.comf5842f72011-05-04 18:30:04 +0000739 *ptr++ = PaintOp_packOpData(kTypeface_PaintOp, id);
740 base.setTypeface(paint.getTypeface());
reed@google.combb6992a2011-04-26 17:41:56 +0000741 }
reed@google.combb6992a2011-04-26 17:41:56 +0000742
reed@google.comb55d1182011-05-11 00:42:04 +0000743 for (int i = 0; i < kCount_PaintFlats; i++) {
744 int index = this->flattenToIndex(get_paintflat(paint, i), (PaintFlats)i);
745 SkASSERT(index >= 0 && index <= fFlatArray.count());
746 if (index != fCurrFlatIndex[i]) {
reed@google.comb55d1182011-05-11 00:42:04 +0000747 *ptr++ = PaintOp_packOpFlagData(kFlatIndex_PaintOp, i, index);
748 fCurrFlatIndex[i] = index;
749 }
750 }
751
reed@google.comacd471f2011-05-03 21:26:46 +0000752 size_t size = (char*)ptr - (char*)storage;
753 if (size && this->needOpBytes(size)) {
reed@google.comb55d1182011-05-11 00:42:04 +0000754 this->writeOp(kPaintOp_DrawOp, 0, size);
reed@google.comb55d1182011-05-11 00:42:04 +0000755 fWriter.write(storage, size);
reed@google.combb6992a2011-04-26 17:41:56 +0000756 for (size_t i = 0; i < size/4; i++) {
reed@google.comb55d1182011-05-11 00:42:04 +0000757// SkDebugf("[%d] %08X\n", i, storage[i]);
reed@google.combb6992a2011-04-26 17:41:56 +0000758 }
759 }
reed@google.combb6992a2011-04-26 17:41:56 +0000760}
761
762///////////////////////////////////////////////////////////////////////////////
763
764#include "SkGPipe.h"
765
reed@google.comacd471f2011-05-03 21:26:46 +0000766SkGPipeWriter::SkGPipeWriter() : fWriter(0) {
reed@google.combb6992a2011-04-26 17:41:56 +0000767 fCanvas = NULL;
768}
769
770SkGPipeWriter::~SkGPipeWriter() {
reed@google.comacd471f2011-05-03 21:26:46 +0000771 this->endRecording();
reed@google.combb6992a2011-04-26 17:41:56 +0000772 SkSafeUnref(fCanvas);
773}
774
reed@google.comdde09562011-05-23 12:21:05 +0000775SkCanvas* SkGPipeWriter::startRecording(SkGPipeController* controller,
776 uint32_t flags) {
reed@google.combb6992a2011-04-26 17:41:56 +0000777 if (NULL == fCanvas) {
reed@google.comacd471f2011-05-03 21:26:46 +0000778 fWriter.reset(NULL, 0);
reed@google.comdde09562011-05-23 12:21:05 +0000779 fFactorySet.reset();
780 fCanvas = SkNEW_ARGS(SkGPipeCanvas, (controller, &fWriter,
781 (flags & kCrossProcess_Flag) ?
782 &fFactorySet : NULL));
reed@google.combb6992a2011-04-26 17:41:56 +0000783 }
784 return fCanvas;
785}
786
787void SkGPipeWriter::endRecording() {
788 if (fCanvas) {
789 fCanvas->finish();
790 fCanvas->unref();
791 fCanvas = NULL;
792 }
793}
794