gfx/skia/trunk/src/pipe/SkGPipeRead.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

michael@0 1
michael@0 2 /*
michael@0 3 * Copyright 2011 Google Inc.
michael@0 4 *
michael@0 5 * Use of this source code is governed by a BSD-style license that can be
michael@0 6 * found in the LICENSE file.
michael@0 7 */
michael@0 8
michael@0 9
michael@0 10 #include "SkBitmapHeap.h"
michael@0 11 #include "SkCanvas.h"
michael@0 12 #include "SkPaint.h"
michael@0 13 #include "SkGPipe.h"
michael@0 14 #include "SkGPipePriv.h"
michael@0 15 #include "SkReader32.h"
michael@0 16 #include "SkStream.h"
michael@0 17
michael@0 18 #include "SkAnnotation.h"
michael@0 19 #include "SkColorFilter.h"
michael@0 20 #include "SkDrawLooper.h"
michael@0 21 #include "SkImageFilter.h"
michael@0 22 #include "SkMaskFilter.h"
michael@0 23 #include "SkReadBuffer.h"
michael@0 24 #include "SkPathEffect.h"
michael@0 25 #include "SkRasterizer.h"
michael@0 26 #include "SkRRect.h"
michael@0 27 #include "SkShader.h"
michael@0 28 #include "SkTypeface.h"
michael@0 29 #include "SkXfermode.h"
michael@0 30
michael@0 31 static SkFlattenable::Type paintflat_to_flattype(PaintFlats pf) {
michael@0 32 static const uint8_t gEffectTypesInPaintFlatsOrder[] = {
michael@0 33 SkFlattenable::kSkColorFilter_Type,
michael@0 34 SkFlattenable::kSkDrawLooper_Type,
michael@0 35 SkFlattenable::kSkImageFilter_Type,
michael@0 36 SkFlattenable::kSkMaskFilter_Type,
michael@0 37 SkFlattenable::kSkPathEffect_Type,
michael@0 38 SkFlattenable::kSkRasterizer_Type,
michael@0 39 SkFlattenable::kSkShader_Type,
michael@0 40 SkFlattenable::kSkXfermode_Type,
michael@0 41 };
michael@0 42
michael@0 43 SkASSERT((size_t)pf < SK_ARRAY_COUNT(gEffectTypesInPaintFlatsOrder));
michael@0 44 return (SkFlattenable::Type)gEffectTypesInPaintFlatsOrder[pf];
michael@0 45 }
michael@0 46
michael@0 47 static void set_paintflat(SkPaint* paint, SkFlattenable* obj, unsigned paintFlat) {
michael@0 48 SkASSERT(paintFlat < kCount_PaintFlats);
michael@0 49 switch (paintFlat) {
michael@0 50 case kColorFilter_PaintFlat:
michael@0 51 paint->setColorFilter((SkColorFilter*)obj);
michael@0 52 break;
michael@0 53 case kDrawLooper_PaintFlat:
michael@0 54 paint->setLooper((SkDrawLooper*)obj);
michael@0 55 break;
michael@0 56 case kMaskFilter_PaintFlat:
michael@0 57 paint->setMaskFilter((SkMaskFilter*)obj);
michael@0 58 break;
michael@0 59 case kPathEffect_PaintFlat:
michael@0 60 paint->setPathEffect((SkPathEffect*)obj);
michael@0 61 break;
michael@0 62 case kRasterizer_PaintFlat:
michael@0 63 paint->setRasterizer((SkRasterizer*)obj);
michael@0 64 break;
michael@0 65 case kShader_PaintFlat:
michael@0 66 paint->setShader((SkShader*)obj);
michael@0 67 break;
michael@0 68 case kImageFilter_PaintFlat:
michael@0 69 paint->setImageFilter((SkImageFilter*)obj);
michael@0 70 break;
michael@0 71 case kXfermode_PaintFlat:
michael@0 72 paint->setXfermode((SkXfermode*)obj);
michael@0 73 break;
michael@0 74 default:
michael@0 75 SkDEBUGFAIL("never gets here");
michael@0 76 }
michael@0 77 }
michael@0 78
michael@0 79 template <typename T> class SkRefCntTDArray : public SkTDArray<T> {
michael@0 80 public:
michael@0 81 ~SkRefCntTDArray() { this->unrefAll(); }
michael@0 82 };
michael@0 83
michael@0 84 class SkGPipeState : public SkBitmapHeapReader {
michael@0 85 public:
michael@0 86 SkGPipeState();
michael@0 87 ~SkGPipeState();
michael@0 88
michael@0 89 void setSilent(bool silent) {
michael@0 90 fSilent = silent;
michael@0 91 }
michael@0 92
michael@0 93 bool shouldDraw() {
michael@0 94 return !fSilent;
michael@0 95 }
michael@0 96
michael@0 97 void setFlags(unsigned flags) {
michael@0 98 if (fFlags != flags) {
michael@0 99 fFlags = flags;
michael@0 100 this->updateReader();
michael@0 101 }
michael@0 102 }
michael@0 103
michael@0 104 unsigned getFlags() const {
michael@0 105 return fFlags;
michael@0 106 }
michael@0 107
michael@0 108 void setReader(SkReadBuffer* reader) {
michael@0 109 fReader = reader;
michael@0 110 this->updateReader();
michael@0 111 }
michael@0 112
michael@0 113 const SkPaint& paint() const { return fPaint; }
michael@0 114 SkPaint* editPaint() { return &fPaint; }
michael@0 115
michael@0 116 SkFlattenable* getFlat(unsigned index) const {
michael@0 117 if (0 == index) {
michael@0 118 return NULL;
michael@0 119 }
michael@0 120 return fFlatArray[index - 1];
michael@0 121 }
michael@0 122
michael@0 123 void defFlattenable(PaintFlats pf, int index) {
michael@0 124 index--;
michael@0 125 SkFlattenable* obj = fReader->readFlattenable(paintflat_to_flattype(pf));
michael@0 126 if (fFlatArray.count() == index) {
michael@0 127 *fFlatArray.append() = obj;
michael@0 128 } else {
michael@0 129 SkSafeUnref(fFlatArray[index]);
michael@0 130 fFlatArray[index] = obj;
michael@0 131 }
michael@0 132 }
michael@0 133
michael@0 134 void defFactory(const char* name) {
michael@0 135 SkFlattenable::Factory factory = SkFlattenable::NameToFactory(name);
michael@0 136 if (factory) {
michael@0 137 SkASSERT(fFactoryArray.find(factory) < 0);
michael@0 138 *fFactoryArray.append() = factory;
michael@0 139 }
michael@0 140 }
michael@0 141
michael@0 142 /**
michael@0 143 * Add a bitmap to the array of bitmaps, or replace an existing one.
michael@0 144 * This is only used when in cross process mode without a shared heap.
michael@0 145 */
michael@0 146 void addBitmap(int index) {
michael@0 147 SkASSERT(shouldFlattenBitmaps(fFlags));
michael@0 148 SkBitmap* bm;
michael@0 149 if(fBitmaps.count() == index) {
michael@0 150 bm = SkNEW(SkBitmap);
michael@0 151 *fBitmaps.append() = bm;
michael@0 152 } else {
michael@0 153 bm = fBitmaps[index];
michael@0 154 }
michael@0 155 fReader->readBitmap(bm);
michael@0 156 }
michael@0 157
michael@0 158 /**
michael@0 159 * Override of SkBitmapHeapReader, so that SkReadBuffer can use
michael@0 160 * these SkBitmaps for bitmap shaders. Used only in cross process mode
michael@0 161 * without a shared heap.
michael@0 162 */
michael@0 163 virtual SkBitmap* getBitmap(int32_t index) const SK_OVERRIDE {
michael@0 164 SkASSERT(shouldFlattenBitmaps(fFlags));
michael@0 165 return fBitmaps[index];
michael@0 166 }
michael@0 167
michael@0 168 /**
michael@0 169 * Needed to be a non-abstract subclass of SkBitmapHeapReader.
michael@0 170 */
michael@0 171 virtual void releaseRef(int32_t) SK_OVERRIDE {}
michael@0 172
michael@0 173 void setSharedHeap(SkBitmapHeap* heap) {
michael@0 174 SkASSERT(!shouldFlattenBitmaps(fFlags) || NULL == heap);
michael@0 175 SkRefCnt_SafeAssign(fSharedHeap, heap);
michael@0 176 this->updateReader();
michael@0 177 }
michael@0 178
michael@0 179 /**
michael@0 180 * Access the shared heap. Only used in the case when bitmaps are not
michael@0 181 * flattened.
michael@0 182 */
michael@0 183 SkBitmapHeap* getSharedHeap() const {
michael@0 184 SkASSERT(!shouldFlattenBitmaps(fFlags));
michael@0 185 return fSharedHeap;
michael@0 186 }
michael@0 187
michael@0 188 void addTypeface() {
michael@0 189 size_t size = fReader->read32();
michael@0 190 const void* data = fReader->skip(SkAlign4(size));
michael@0 191 SkMemoryStream stream(data, size, false);
michael@0 192 *fTypefaces.append() = SkTypeface::Deserialize(&stream);
michael@0 193 }
michael@0 194
michael@0 195 void setTypeface(SkPaint* paint, unsigned id) {
michael@0 196 paint->setTypeface(id ? fTypefaces[id - 1] : NULL);
michael@0 197 }
michael@0 198
michael@0 199 private:
michael@0 200 void updateReader() {
michael@0 201 if (NULL == fReader) {
michael@0 202 return;
michael@0 203 }
michael@0 204 bool crossProcess = SkToBool(fFlags & SkGPipeWriter::kCrossProcess_Flag);
michael@0 205 fReader->setFlags(SkSetClearMask(fReader->getFlags(), crossProcess,
michael@0 206 SkReadBuffer::kCrossProcess_Flag));
michael@0 207 if (crossProcess) {
michael@0 208 fReader->setFactoryArray(&fFactoryArray);
michael@0 209 } else {
michael@0 210 fReader->setFactoryArray(NULL);
michael@0 211 }
michael@0 212
michael@0 213 if (shouldFlattenBitmaps(fFlags)) {
michael@0 214 fReader->setBitmapStorage(this);
michael@0 215 } else {
michael@0 216 fReader->setBitmapStorage(fSharedHeap);
michael@0 217 }
michael@0 218 }
michael@0 219 SkReadBuffer* fReader;
michael@0 220 SkPaint fPaint;
michael@0 221 SkTDArray<SkFlattenable*> fFlatArray;
michael@0 222 SkTDArray<SkTypeface*> fTypefaces;
michael@0 223 SkTDArray<SkFlattenable::Factory> fFactoryArray;
michael@0 224 SkTDArray<SkBitmap*> fBitmaps;
michael@0 225 bool fSilent;
michael@0 226 // Only used when sharing bitmaps with the writer.
michael@0 227 SkBitmapHeap* fSharedHeap;
michael@0 228 unsigned fFlags;
michael@0 229 };
michael@0 230
michael@0 231 ///////////////////////////////////////////////////////////////////////////////
michael@0 232
michael@0 233 template <typename T> const T* skip(SkReader32* reader, int count = 1) {
michael@0 234 SkASSERT(count >= 0);
michael@0 235 size_t size = sizeof(T) * count;
michael@0 236 SkASSERT(SkAlign4(size) == size);
michael@0 237 return reinterpret_cast<const T*>(reader->skip(size));
michael@0 238 }
michael@0 239
michael@0 240 template <typename T> const T* skipAlign(SkReader32* reader, int count = 1) {
michael@0 241 SkASSERT(count >= 0);
michael@0 242 size_t size = SkAlign4(sizeof(T) * count);
michael@0 243 return reinterpret_cast<const T*>(reader->skip(size));
michael@0 244 }
michael@0 245
michael@0 246 ///////////////////////////////////////////////////////////////////////////////
michael@0 247 ///////////////////////////////////////////////////////////////////////////////
michael@0 248
michael@0 249 static void clipPath_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
michael@0 250 SkGPipeState* state) {
michael@0 251 SkPath path;
michael@0 252 reader->readPath(&path);
michael@0 253 bool doAA = SkToBool(DrawOp_unpackFlags(op32) & kClip_HasAntiAlias_DrawOpFlag);
michael@0 254 canvas->clipPath(path, (SkRegion::Op)DrawOp_unpackData(op32), doAA);
michael@0 255 }
michael@0 256
michael@0 257 static void clipRegion_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
michael@0 258 SkGPipeState* state) {
michael@0 259 SkRegion rgn;
michael@0 260 reader->readRegion(&rgn);
michael@0 261 canvas->clipRegion(rgn, (SkRegion::Op)DrawOp_unpackData(op32));
michael@0 262 }
michael@0 263
michael@0 264 static void clipRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
michael@0 265 SkGPipeState* state) {
michael@0 266 const SkRect* rect = skip<SkRect>(reader);
michael@0 267 bool doAA = SkToBool(DrawOp_unpackFlags(op32) & kClip_HasAntiAlias_DrawOpFlag);
michael@0 268 canvas->clipRect(*rect, (SkRegion::Op)DrawOp_unpackData(op32), doAA);
michael@0 269 }
michael@0 270
michael@0 271 static void clipRRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
michael@0 272 SkGPipeState* state) {
michael@0 273 SkRRect rrect;
michael@0 274 reader->readRRect(&rrect);
michael@0 275 bool doAA = SkToBool(DrawOp_unpackFlags(op32) & kClip_HasAntiAlias_DrawOpFlag);
michael@0 276 canvas->clipRRect(rrect, (SkRegion::Op)DrawOp_unpackData(op32), doAA);
michael@0 277 }
michael@0 278
michael@0 279 ///////////////////////////////////////////////////////////////////////////////
michael@0 280
michael@0 281 static void setMatrix_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
michael@0 282 SkGPipeState* state) {
michael@0 283 SkMatrix matrix;
michael@0 284 reader->readMatrix(&matrix);
michael@0 285 canvas->setMatrix(matrix);
michael@0 286 }
michael@0 287
michael@0 288 static void concat_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
michael@0 289 SkGPipeState* state) {
michael@0 290 SkMatrix matrix;
michael@0 291 reader->readMatrix(&matrix);
michael@0 292 canvas->concat(matrix);
michael@0 293 }
michael@0 294
michael@0 295 static void scale_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
michael@0 296 SkGPipeState* state) {
michael@0 297 const SkScalar* param = skip<SkScalar>(reader, 2);
michael@0 298 canvas->scale(param[0], param[1]);
michael@0 299 }
michael@0 300
michael@0 301 static void skew_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
michael@0 302 SkGPipeState* state) {
michael@0 303 const SkScalar* param = skip<SkScalar>(reader, 2);
michael@0 304 canvas->skew(param[0], param[1]);
michael@0 305 }
michael@0 306
michael@0 307 static void rotate_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
michael@0 308 SkGPipeState* state) {
michael@0 309 canvas->rotate(reader->readScalar());
michael@0 310 }
michael@0 311
michael@0 312 static void translate_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
michael@0 313 SkGPipeState* state) {
michael@0 314 const SkScalar* param = skip<SkScalar>(reader, 2);
michael@0 315 canvas->translate(param[0], param[1]);
michael@0 316 }
michael@0 317
michael@0 318 ///////////////////////////////////////////////////////////////////////////////
michael@0 319
michael@0 320 static void save_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
michael@0 321 SkGPipeState* state) {
michael@0 322 canvas->save((SkCanvas::SaveFlags)DrawOp_unpackData(op32));
michael@0 323 }
michael@0 324
michael@0 325 static void saveLayer_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
michael@0 326 SkGPipeState* state) {
michael@0 327 unsigned flags = DrawOp_unpackFlags(op32);
michael@0 328 SkCanvas::SaveFlags saveFlags = (SkCanvas::SaveFlags)DrawOp_unpackData(op32);
michael@0 329
michael@0 330 const SkRect* bounds = NULL;
michael@0 331 if (flags & kSaveLayer_HasBounds_DrawOpFlag) {
michael@0 332 bounds = skip<SkRect>(reader);
michael@0 333 }
michael@0 334 const SkPaint* paint = NULL;
michael@0 335 if (flags & kSaveLayer_HasPaint_DrawOpFlag) {
michael@0 336 paint = &state->paint();
michael@0 337 }
michael@0 338 canvas->saveLayer(bounds, paint, saveFlags);
michael@0 339 }
michael@0 340
michael@0 341 static void restore_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
michael@0 342 SkGPipeState* state) {
michael@0 343 canvas->restore();
michael@0 344 }
michael@0 345
michael@0 346 ///////////////////////////////////////////////////////////////////////////////
michael@0 347
michael@0 348 static void drawClear_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
michael@0 349 SkGPipeState* state) {
michael@0 350 SkColor color = 0;
michael@0 351 if (DrawOp_unpackFlags(op32) & kClear_HasColor_DrawOpFlag) {
michael@0 352 color = reader->readU32();
michael@0 353 }
michael@0 354 canvas->clear(color);
michael@0 355 }
michael@0 356
michael@0 357 static void drawPaint_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
michael@0 358 SkGPipeState* state) {
michael@0 359 if (state->shouldDraw()) {
michael@0 360 canvas->drawPaint(state->paint());
michael@0 361 }
michael@0 362 }
michael@0 363
michael@0 364 static void drawPoints_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
michael@0 365 SkGPipeState* state) {
michael@0 366 SkCanvas::PointMode mode = (SkCanvas::PointMode)DrawOp_unpackFlags(op32);
michael@0 367 size_t count = reader->readU32();
michael@0 368 const SkPoint* pts = skip<SkPoint>(reader, count);
michael@0 369 if (state->shouldDraw()) {
michael@0 370 canvas->drawPoints(mode, count, pts, state->paint());
michael@0 371 }
michael@0 372 }
michael@0 373
michael@0 374 static void drawOval_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
michael@0 375 SkGPipeState* state) {
michael@0 376 const SkRect* rect = skip<SkRect>(reader);
michael@0 377 if (state->shouldDraw()) {
michael@0 378 canvas->drawOval(*rect, state->paint());
michael@0 379 }
michael@0 380 }
michael@0 381
michael@0 382 static void drawRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
michael@0 383 SkGPipeState* state) {
michael@0 384 const SkRect* rect = skip<SkRect>(reader);
michael@0 385 if (state->shouldDraw()) {
michael@0 386 canvas->drawRect(*rect, state->paint());
michael@0 387 }
michael@0 388 }
michael@0 389
michael@0 390 static void drawRRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
michael@0 391 SkGPipeState* state) {
michael@0 392 SkRRect rrect;
michael@0 393 reader->readRRect(&rrect);
michael@0 394 if (state->shouldDraw()) {
michael@0 395 canvas->drawRRect(rrect, state->paint());
michael@0 396 }
michael@0 397 }
michael@0 398
michael@0 399 static void drawDRRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
michael@0 400 SkGPipeState* state) {
michael@0 401 SkRRect outer, inner;
michael@0 402 reader->readRRect(&outer);
michael@0 403 reader->readRRect(&inner);
michael@0 404 if (state->shouldDraw()) {
michael@0 405 canvas->drawDRRect(outer, inner, state->paint());
michael@0 406 }
michael@0 407 }
michael@0 408
michael@0 409 static void drawPath_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
michael@0 410 SkGPipeState* state) {
michael@0 411 SkPath path;
michael@0 412 reader->readPath(&path);
michael@0 413 if (state->shouldDraw()) {
michael@0 414 canvas->drawPath(path, state->paint());
michael@0 415 }
michael@0 416 }
michael@0 417
michael@0 418 static void drawVertices_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
michael@0 419 SkGPipeState* state) {
michael@0 420 unsigned flags = DrawOp_unpackFlags(op32);
michael@0 421
michael@0 422 SkCanvas::VertexMode vmode = (SkCanvas::VertexMode)reader->readU32();
michael@0 423 int vertexCount = reader->readU32();
michael@0 424 const SkPoint* verts = skip<SkPoint>(reader, vertexCount);
michael@0 425
michael@0 426 const SkPoint* texs = NULL;
michael@0 427 if (flags & kDrawVertices_HasTexs_DrawOpFlag) {
michael@0 428 texs = skip<SkPoint>(reader, vertexCount);
michael@0 429 }
michael@0 430
michael@0 431 const SkColor* colors = NULL;
michael@0 432 if (flags & kDrawVertices_HasColors_DrawOpFlag) {
michael@0 433 colors = skip<SkColor>(reader, vertexCount);
michael@0 434 }
michael@0 435
michael@0 436 SkAutoTUnref<SkXfermode> xfer;
michael@0 437 if (flags & kDrawVertices_HasXfermode_DrawOpFlag) {
michael@0 438 SkXfermode::Mode mode = (SkXfermode::Mode)reader->readU32();
michael@0 439 xfer.reset(SkXfermode::Create(mode));
michael@0 440 }
michael@0 441
michael@0 442 int indexCount = 0;
michael@0 443 const uint16_t* indices = NULL;
michael@0 444 if (flags & kDrawVertices_HasIndices_DrawOpFlag) {
michael@0 445 indexCount = reader->readU32();
michael@0 446 indices = skipAlign<uint16_t>(reader, indexCount);
michael@0 447 }
michael@0 448 if (state->shouldDraw()) {
michael@0 449 canvas->drawVertices(vmode, vertexCount, verts, texs, colors, xfer,
michael@0 450 indices, indexCount, state->paint());
michael@0 451 }
michael@0 452 }
michael@0 453
michael@0 454 ///////////////////////////////////////////////////////////////////////////////
michael@0 455
michael@0 456 static void drawText_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
michael@0 457 SkGPipeState* state) {
michael@0 458 size_t len = reader->readU32();
michael@0 459 const void* text = reader->skip(SkAlign4(len));
michael@0 460 const SkScalar* xy = skip<SkScalar>(reader, 2);
michael@0 461 if (state->shouldDraw()) {
michael@0 462 canvas->drawText(text, len, xy[0], xy[1], state->paint());
michael@0 463 }
michael@0 464 }
michael@0 465
michael@0 466 static void drawPosText_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
michael@0 467 SkGPipeState* state) {
michael@0 468 size_t len = reader->readU32();
michael@0 469 const void* text = reader->skip(SkAlign4(len));
michael@0 470 size_t posCount = reader->readU32(); // compute by our writer
michael@0 471 const SkPoint* pos = skip<SkPoint>(reader, posCount);
michael@0 472 if (state->shouldDraw()) {
michael@0 473 canvas->drawPosText(text, len, pos, state->paint());
michael@0 474 }
michael@0 475 }
michael@0 476
michael@0 477 static void drawPosTextH_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
michael@0 478 SkGPipeState* state) {
michael@0 479 size_t len = reader->readU32();
michael@0 480 const void* text = reader->skip(SkAlign4(len));
michael@0 481 size_t posCount = reader->readU32(); // compute by our writer
michael@0 482 const SkScalar* xpos = skip<SkScalar>(reader, posCount);
michael@0 483 SkScalar constY = reader->readScalar();
michael@0 484 if (state->shouldDraw()) {
michael@0 485 canvas->drawPosTextH(text, len, xpos, constY, state->paint());
michael@0 486 }
michael@0 487 }
michael@0 488
michael@0 489 static void drawTextOnPath_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
michael@0 490 SkGPipeState* state) {
michael@0 491 size_t len = reader->readU32();
michael@0 492 const void* text = reader->skip(SkAlign4(len));
michael@0 493
michael@0 494 SkPath path;
michael@0 495 reader->readPath(&path);
michael@0 496
michael@0 497 SkMatrix matrixStorage;
michael@0 498 const SkMatrix* matrix = NULL;
michael@0 499 if (DrawOp_unpackFlags(op32) & kDrawTextOnPath_HasMatrix_DrawOpFlag) {
michael@0 500 reader->readMatrix(&matrixStorage);
michael@0 501 matrix = &matrixStorage;
michael@0 502 }
michael@0 503 if (state->shouldDraw()) {
michael@0 504 canvas->drawTextOnPath(text, len, path, matrix, state->paint());
michael@0 505 }
michael@0 506 }
michael@0 507
michael@0 508 ///////////////////////////////////////////////////////////////////////////////
michael@0 509
michael@0 510 class BitmapHolder : SkNoncopyable {
michael@0 511 public:
michael@0 512 BitmapHolder(SkReader32* reader, uint32_t op32, SkGPipeState* state);
michael@0 513 ~BitmapHolder() {
michael@0 514 if (fHeapEntry != NULL) {
michael@0 515 fHeapEntry->releaseRef();
michael@0 516 }
michael@0 517 }
michael@0 518 const SkBitmap* getBitmap() {
michael@0 519 return fBitmap;
michael@0 520 }
michael@0 521 private:
michael@0 522 SkBitmapHeapEntry* fHeapEntry;
michael@0 523 const SkBitmap* fBitmap;
michael@0 524 SkBitmap fBitmapStorage;
michael@0 525 };
michael@0 526
michael@0 527 BitmapHolder::BitmapHolder(SkReader32* reader, uint32_t op32,
michael@0 528 SkGPipeState* state) {
michael@0 529 const unsigned flags = state->getFlags();
michael@0 530 const unsigned index = DrawOp_unpackData(op32);
michael@0 531 if (shouldFlattenBitmaps(flags)) {
michael@0 532 fHeapEntry = NULL;
michael@0 533 fBitmap = state->getBitmap(index);
michael@0 534 } else {
michael@0 535 SkBitmapHeapEntry* entry = state->getSharedHeap()->getEntry(index);
michael@0 536 if (SkToBool(flags & SkGPipeWriter::kSimultaneousReaders_Flag)) {
michael@0 537 // Make a shallow copy for thread safety. Each thread will point to the same SkPixelRef,
michael@0 538 // which is thread safe.
michael@0 539 fBitmapStorage = *entry->getBitmap();
michael@0 540 fBitmap = &fBitmapStorage;
michael@0 541 // Release the ref on the bitmap now, since we made our own copy.
michael@0 542 entry->releaseRef();
michael@0 543 fHeapEntry = NULL;
michael@0 544 } else {
michael@0 545 SkASSERT(!shouldFlattenBitmaps(flags));
michael@0 546 SkASSERT(!SkToBool(flags & SkGPipeWriter::kSimultaneousReaders_Flag));
michael@0 547 fHeapEntry = entry;
michael@0 548 fBitmap = fHeapEntry->getBitmap();
michael@0 549 }
michael@0 550 }
michael@0 551 }
michael@0 552
michael@0 553 static void drawBitmap_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
michael@0 554 SkGPipeState* state) {
michael@0 555 BitmapHolder holder(reader, op32, state);
michael@0 556 bool hasPaint = SkToBool(DrawOp_unpackFlags(op32) & kDrawBitmap_HasPaint_DrawOpFlag);
michael@0 557 SkScalar left = reader->readScalar();
michael@0 558 SkScalar top = reader->readScalar();
michael@0 559 const SkBitmap* bitmap = holder.getBitmap();
michael@0 560 if (state->shouldDraw()) {
michael@0 561 canvas->drawBitmap(*bitmap, left, top, hasPaint ? &state->paint() : NULL);
michael@0 562 }
michael@0 563 }
michael@0 564
michael@0 565 static void drawBitmapMatrix_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
michael@0 566 SkGPipeState* state) {
michael@0 567 BitmapHolder holder(reader, op32, state);
michael@0 568 bool hasPaint = SkToBool(DrawOp_unpackFlags(op32) & kDrawBitmap_HasPaint_DrawOpFlag);
michael@0 569 SkMatrix matrix;
michael@0 570 reader->readMatrix(&matrix);
michael@0 571 const SkBitmap* bitmap = holder.getBitmap();
michael@0 572 if (state->shouldDraw()) {
michael@0 573 canvas->drawBitmapMatrix(*bitmap, matrix,
michael@0 574 hasPaint ? &state->paint() : NULL);
michael@0 575 }
michael@0 576 }
michael@0 577
michael@0 578 static void drawBitmapNine_rp(SkCanvas* canvas, SkReader32* reader,
michael@0 579 uint32_t op32, SkGPipeState* state) {
michael@0 580 BitmapHolder holder(reader, op32, state);
michael@0 581 bool hasPaint = SkToBool(DrawOp_unpackFlags(op32) & kDrawBitmap_HasPaint_DrawOpFlag);
michael@0 582 const SkIRect* center = skip<SkIRect>(reader);
michael@0 583 const SkRect* dst = skip<SkRect>(reader);
michael@0 584 const SkBitmap* bitmap = holder.getBitmap();
michael@0 585 if (state->shouldDraw()) {
michael@0 586 canvas->drawBitmapNine(*bitmap, *center, *dst,
michael@0 587 hasPaint ? &state->paint() : NULL);
michael@0 588 }
michael@0 589 }
michael@0 590
michael@0 591 static void drawBitmapRect_rp(SkCanvas* canvas, SkReader32* reader,
michael@0 592 uint32_t op32, SkGPipeState* state) {
michael@0 593 BitmapHolder holder(reader, op32, state);
michael@0 594 unsigned flags = DrawOp_unpackFlags(op32);
michael@0 595 bool hasPaint = SkToBool(flags & kDrawBitmap_HasPaint_DrawOpFlag);
michael@0 596 bool hasSrc = SkToBool(flags & kDrawBitmap_HasSrcRect_DrawOpFlag);
michael@0 597 const SkRect* src;
michael@0 598 if (hasSrc) {
michael@0 599 src = skip<SkRect>(reader);
michael@0 600 } else {
michael@0 601 src = NULL;
michael@0 602 }
michael@0 603 SkCanvas::DrawBitmapRectFlags dbmrFlags = SkCanvas::kNone_DrawBitmapRectFlag;
michael@0 604 if (flags & kDrawBitmap_Bleed_DrawOpFlag) {
michael@0 605 dbmrFlags = (SkCanvas::DrawBitmapRectFlags)(dbmrFlags|SkCanvas::kBleed_DrawBitmapRectFlag);
michael@0 606 }
michael@0 607 const SkRect* dst = skip<SkRect>(reader);
michael@0 608 const SkBitmap* bitmap = holder.getBitmap();
michael@0 609 if (state->shouldDraw()) {
michael@0 610 canvas->drawBitmapRectToRect(*bitmap, src, *dst,
michael@0 611 hasPaint ? &state->paint() : NULL, dbmrFlags);
michael@0 612 }
michael@0 613 }
michael@0 614
michael@0 615 static void drawSprite_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
michael@0 616 SkGPipeState* state) {
michael@0 617 BitmapHolder holder(reader, op32, state);
michael@0 618 bool hasPaint = SkToBool(DrawOp_unpackFlags(op32) & kDrawBitmap_HasPaint_DrawOpFlag);
michael@0 619 const SkIPoint* point = skip<SkIPoint>(reader);
michael@0 620 const SkBitmap* bitmap = holder.getBitmap();
michael@0 621 if (state->shouldDraw()) {
michael@0 622 canvas->drawSprite(*bitmap, point->fX, point->fY, hasPaint ? &state->paint() : NULL);
michael@0 623 }
michael@0 624 }
michael@0 625
michael@0 626 ///////////////////////////////////////////////////////////////////////////////
michael@0 627
michael@0 628 static void drawData_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
michael@0 629 SkGPipeState* state) {
michael@0 630 // since we don't have a paint, we can use data for our (small) sizes
michael@0 631 size_t size = DrawOp_unpackData(op32);
michael@0 632 if (0 == size) {
michael@0 633 size = reader->readU32();
michael@0 634 }
michael@0 635 const void* data = reader->skip(SkAlign4(size));
michael@0 636 if (state->shouldDraw()) {
michael@0 637 canvas->drawData(data, size);
michael@0 638 }
michael@0 639 }
michael@0 640
michael@0 641 static void drawPicture_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
michael@0 642 SkGPipeState* state) {
michael@0 643 UNIMPLEMENTED
michael@0 644 }
michael@0 645
michael@0 646 ///////////////////////////////////////////////////////////////////////////////
michael@0 647
michael@0 648 static void paintOp_rp(SkCanvas*, SkReader32* reader, uint32_t op32,
michael@0 649 SkGPipeState* state) {
michael@0 650 size_t offset = reader->offset();
michael@0 651 size_t stop = offset + PaintOp_unpackData(op32);
michael@0 652 SkPaint* p = state->editPaint();
michael@0 653
michael@0 654 do {
michael@0 655 uint32_t p32 = reader->readU32();
michael@0 656 unsigned op = PaintOp_unpackOp(p32);
michael@0 657 unsigned data = PaintOp_unpackData(p32);
michael@0 658
michael@0 659 // SkDebugf(" read %08X op=%d flags=%d data=%d\n", p32, op, done, data);
michael@0 660
michael@0 661 switch (op) {
michael@0 662 case kReset_PaintOp: p->reset(); break;
michael@0 663 case kFlags_PaintOp: p->setFlags(data); break;
michael@0 664 case kColor_PaintOp: p->setColor(reader->readU32()); break;
michael@0 665 case kStyle_PaintOp: p->setStyle((SkPaint::Style)data); break;
michael@0 666 case kJoin_PaintOp: p->setStrokeJoin((SkPaint::Join)data); break;
michael@0 667 case kCap_PaintOp: p->setStrokeCap((SkPaint::Cap)data); break;
michael@0 668 case kWidth_PaintOp: p->setStrokeWidth(reader->readScalar()); break;
michael@0 669 case kMiter_PaintOp: p->setStrokeMiter(reader->readScalar()); break;
michael@0 670 case kEncoding_PaintOp:
michael@0 671 p->setTextEncoding((SkPaint::TextEncoding)data);
michael@0 672 break;
michael@0 673 case kHinting_PaintOp: p->setHinting((SkPaint::Hinting)data); break;
michael@0 674 case kAlign_PaintOp: p->setTextAlign((SkPaint::Align)data); break;
michael@0 675 case kTextSize_PaintOp: p->setTextSize(reader->readScalar()); break;
michael@0 676 case kTextScaleX_PaintOp: p->setTextScaleX(reader->readScalar()); break;
michael@0 677 case kTextSkewX_PaintOp: p->setTextSkewX(reader->readScalar()); break;
michael@0 678
michael@0 679 case kFlatIndex_PaintOp: {
michael@0 680 PaintFlats pf = (PaintFlats)PaintOp_unpackFlags(p32);
michael@0 681 unsigned index = data;
michael@0 682 set_paintflat(p, state->getFlat(index), pf);
michael@0 683 break;
michael@0 684 }
michael@0 685
michael@0 686 case kTypeface_PaintOp:
michael@0 687 SkASSERT(SkToBool(state->getFlags() &
michael@0 688 SkGPipeWriter::kCrossProcess_Flag));
michael@0 689 state->setTypeface(p, data); break;
michael@0 690 default: SkDEBUGFAIL("bad paintop"); return;
michael@0 691 }
michael@0 692 SkASSERT(reader->offset() <= stop);
michael@0 693 } while (reader->offset() < stop);
michael@0 694 }
michael@0 695
michael@0 696 static void typeface_rp(SkCanvas*, SkReader32* reader, uint32_t,
michael@0 697 SkGPipeState* state) {
michael@0 698 SkASSERT(!SkToBool(state->getFlags() & SkGPipeWriter::kCrossProcess_Flag));
michael@0 699 SkPaint* p = state->editPaint();
michael@0 700 p->setTypeface(static_cast<SkTypeface*>(reader->readPtr()));
michael@0 701 }
michael@0 702
michael@0 703 static void annotation_rp(SkCanvas*, SkReader32* reader, uint32_t op32,
michael@0 704 SkGPipeState* state) {
michael@0 705 SkPaint* p = state->editPaint();
michael@0 706
michael@0 707 const size_t size = DrawOp_unpackData(op32);
michael@0 708 if (size > 0) {
michael@0 709 SkReadBuffer buffer(reader->skip(size), size);
michael@0 710 p->setAnnotation(SkAnnotation::Create(buffer))->unref();
michael@0 711 SkASSERT(buffer.offset() == size);
michael@0 712 } else {
michael@0 713 p->setAnnotation(NULL);
michael@0 714 }
michael@0 715 }
michael@0 716
michael@0 717 ///////////////////////////////////////////////////////////////////////////////
michael@0 718
michael@0 719 static void def_Typeface_rp(SkCanvas*, SkReader32*, uint32_t, SkGPipeState* state) {
michael@0 720 state->addTypeface();
michael@0 721 }
michael@0 722
michael@0 723 static void def_PaintFlat_rp(SkCanvas*, SkReader32*, uint32_t op32,
michael@0 724 SkGPipeState* state) {
michael@0 725 PaintFlats pf = (PaintFlats)DrawOp_unpackFlags(op32);
michael@0 726 unsigned index = DrawOp_unpackData(op32);
michael@0 727 state->defFlattenable(pf, index);
michael@0 728 }
michael@0 729
michael@0 730 static void def_Bitmap_rp(SkCanvas*, SkReader32*, uint32_t op32,
michael@0 731 SkGPipeState* state) {
michael@0 732 unsigned index = DrawOp_unpackData(op32);
michael@0 733 state->addBitmap(index);
michael@0 734 }
michael@0 735
michael@0 736 static void def_Factory_rp(SkCanvas*, SkReader32* reader, uint32_t,
michael@0 737 SkGPipeState* state) {
michael@0 738 state->defFactory(reader->readString());
michael@0 739 }
michael@0 740
michael@0 741 ///////////////////////////////////////////////////////////////////////////////
michael@0 742
michael@0 743 static void skip_rp(SkCanvas*, SkReader32* reader, uint32_t op32, SkGPipeState*) {
michael@0 744 size_t bytes = DrawOp_unpackData(op32);
michael@0 745 (void)reader->skip(bytes);
michael@0 746 }
michael@0 747
michael@0 748 static void reportFlags_rp(SkCanvas*, SkReader32*, uint32_t op32,
michael@0 749 SkGPipeState* state) {
michael@0 750 unsigned flags = DrawOp_unpackFlags(op32);
michael@0 751 state->setFlags(flags);
michael@0 752 }
michael@0 753
michael@0 754 static void shareBitmapHeap_rp(SkCanvas*, SkReader32* reader, uint32_t,
michael@0 755 SkGPipeState* state) {
michael@0 756 state->setSharedHeap(static_cast<SkBitmapHeap*>(reader->readPtr()));
michael@0 757 }
michael@0 758
michael@0 759 static void done_rp(SkCanvas*, SkReader32*, uint32_t, SkGPipeState*) {}
michael@0 760
michael@0 761 typedef void (*ReadProc)(SkCanvas*, SkReader32*, uint32_t op32, SkGPipeState*);
michael@0 762
michael@0 763 static const ReadProc gReadTable[] = {
michael@0 764 skip_rp,
michael@0 765 clipPath_rp,
michael@0 766 clipRegion_rp,
michael@0 767 clipRect_rp,
michael@0 768 clipRRect_rp,
michael@0 769 concat_rp,
michael@0 770 drawBitmap_rp,
michael@0 771 drawBitmapMatrix_rp,
michael@0 772 drawBitmapNine_rp,
michael@0 773 drawBitmapRect_rp,
michael@0 774 drawClear_rp,
michael@0 775 drawData_rp,
michael@0 776 drawDRRect_rp,
michael@0 777 drawOval_rp,
michael@0 778 drawPaint_rp,
michael@0 779 drawPath_rp,
michael@0 780 drawPicture_rp,
michael@0 781 drawPoints_rp,
michael@0 782 drawPosText_rp,
michael@0 783 drawPosTextH_rp,
michael@0 784 drawRect_rp,
michael@0 785 drawRRect_rp,
michael@0 786 drawSprite_rp,
michael@0 787 drawText_rp,
michael@0 788 drawTextOnPath_rp,
michael@0 789 drawVertices_rp,
michael@0 790 restore_rp,
michael@0 791 rotate_rp,
michael@0 792 save_rp,
michael@0 793 saveLayer_rp,
michael@0 794 scale_rp,
michael@0 795 setMatrix_rp,
michael@0 796 skew_rp,
michael@0 797 translate_rp,
michael@0 798
michael@0 799 paintOp_rp,
michael@0 800 typeface_rp,
michael@0 801 annotation_rp,
michael@0 802
michael@0 803 def_Typeface_rp,
michael@0 804 def_PaintFlat_rp,
michael@0 805 def_Bitmap_rp,
michael@0 806 def_Factory_rp,
michael@0 807
michael@0 808 reportFlags_rp,
michael@0 809 shareBitmapHeap_rp,
michael@0 810 done_rp
michael@0 811 };
michael@0 812
michael@0 813 ///////////////////////////////////////////////////////////////////////////////
michael@0 814
michael@0 815 SkGPipeState::SkGPipeState()
michael@0 816 : fReader(0)
michael@0 817 , fSilent(false)
michael@0 818 , fSharedHeap(NULL)
michael@0 819 , fFlags(0) {
michael@0 820
michael@0 821 }
michael@0 822
michael@0 823 SkGPipeState::~SkGPipeState() {
michael@0 824 fTypefaces.safeUnrefAll();
michael@0 825 fFlatArray.safeUnrefAll();
michael@0 826 fBitmaps.deleteAll();
michael@0 827 SkSafeUnref(fSharedHeap);
michael@0 828 }
michael@0 829
michael@0 830 ///////////////////////////////////////////////////////////////////////////////
michael@0 831
michael@0 832 #include "SkGPipe.h"
michael@0 833
michael@0 834 SkGPipeReader::SkGPipeReader() {
michael@0 835 fCanvas = NULL;
michael@0 836 fState = NULL;
michael@0 837 fProc = NULL;
michael@0 838 }
michael@0 839
michael@0 840 SkGPipeReader::SkGPipeReader(SkCanvas* target) {
michael@0 841 fCanvas = NULL;
michael@0 842 this->setCanvas(target);
michael@0 843 fState = NULL;
michael@0 844 fProc = NULL;
michael@0 845 }
michael@0 846
michael@0 847 void SkGPipeReader::setCanvas(SkCanvas *target) {
michael@0 848 SkRefCnt_SafeAssign(fCanvas, target);
michael@0 849 }
michael@0 850
michael@0 851 SkGPipeReader::~SkGPipeReader() {
michael@0 852 SkSafeUnref(fCanvas);
michael@0 853 delete fState;
michael@0 854 }
michael@0 855
michael@0 856 SkGPipeReader::Status SkGPipeReader::playback(const void* data, size_t length,
michael@0 857 uint32_t playbackFlags, size_t* bytesRead) {
michael@0 858 if (NULL == fCanvas) {
michael@0 859 return kError_Status;
michael@0 860 }
michael@0 861
michael@0 862 if (NULL == fState) {
michael@0 863 fState = new SkGPipeState;
michael@0 864 }
michael@0 865
michael@0 866 fState->setSilent(playbackFlags & kSilent_PlaybackFlag);
michael@0 867
michael@0 868 SkASSERT(SK_ARRAY_COUNT(gReadTable) == (kDone_DrawOp + 1));
michael@0 869
michael@0 870 const ReadProc* table = gReadTable;
michael@0 871 SkReadBuffer reader(data, length);
michael@0 872 reader.setBitmapDecoder(fProc);
michael@0 873 SkCanvas* canvas = fCanvas;
michael@0 874 Status status = kEOF_Status;
michael@0 875
michael@0 876 fState->setReader(&reader);
michael@0 877 while (!reader.eof()) {
michael@0 878 uint32_t op32 = reader.readUInt();
michael@0 879 unsigned op = DrawOp_unpackOp(op32);
michael@0 880 // SkDEBUGCODE(DrawOps drawOp = (DrawOps)op;)
michael@0 881
michael@0 882 if (op >= SK_ARRAY_COUNT(gReadTable)) {
michael@0 883 SkDebugf("---- bad op during GPipeState::playback\n");
michael@0 884 status = kError_Status;
michael@0 885 break;
michael@0 886 }
michael@0 887 if (kDone_DrawOp == op) {
michael@0 888 status = kDone_Status;
michael@0 889 break;
michael@0 890 }
michael@0 891 table[op](canvas, reader.getReader32(), op32, fState);
michael@0 892 if ((playbackFlags & kReadAtom_PlaybackFlag) &&
michael@0 893 (table[op] != paintOp_rp &&
michael@0 894 table[op] != def_Typeface_rp &&
michael@0 895 table[op] != def_PaintFlat_rp &&
michael@0 896 table[op] != def_Bitmap_rp
michael@0 897 )) {
michael@0 898 status = kReadAtom_Status;
michael@0 899 break;
michael@0 900 }
michael@0 901 }
michael@0 902
michael@0 903 if (bytesRead) {
michael@0 904 *bytesRead = reader.offset();
michael@0 905 }
michael@0 906 return status;
michael@0 907 }

mercurial