SkPictureRecord.cpp revision 1fc4c605def61d9e10489f9cd63dc378baa6ade3
1#include "SkPictureRecord.h" 2#include "SkShape.h" 3#include "SkTSearch.h" 4 5#define MIN_WRITER_SIZE 16384 6#define HEAP_BLOCK_SIZE 4096 7 8SkPictureRecord::SkPictureRecord(uint32_t flags) : 9 fHeap(HEAP_BLOCK_SIZE), fWriter(MIN_WRITER_SIZE), fRecordFlags(flags) { 10 fBitmapIndex = fMatrixIndex = fPaintIndex = fRegionIndex = 1; 11#ifdef SK_DEBUG_SIZE 12 fPointBytes = fRectBytes = fTextBytes = 0; 13 fPointWrites = fRectWrites = fTextWrites = 0; 14#endif 15 16 fRestoreOffsetStack.setReserve(32); 17 fRestoreOffsetStack.push(0); 18 19 fPathHeap = NULL; // lazy allocate 20} 21 22SkPictureRecord::~SkPictureRecord() { 23 reset(); 24} 25 26/////////////////////////////////////////////////////////////////////////////// 27 28int SkPictureRecord::save(SaveFlags flags) { 29 addDraw(SAVE); 30 addInt(flags); 31 32 fRestoreOffsetStack.push(0); 33 34 validate(); 35 return this->INHERITED::save(flags); 36} 37 38int SkPictureRecord::saveLayer(const SkRect* bounds, const SkPaint* paint, 39 SaveFlags flags) { 40 addDraw(SAVE_LAYER); 41 addRectPtr(bounds); 42 addPaintPtr(paint); 43 addInt(flags); 44 45 fRestoreOffsetStack.push(0); 46 47 validate(); 48 return this->INHERITED::saveLayer(bounds, paint, flags); 49} 50 51void SkPictureRecord::restore() { 52 // check for underflow 53 if (fRestoreOffsetStack.count() == 0) { 54 return; 55 } 56 57 // patch up the clip offsets 58 uint32_t restoreOffset = (uint32_t)fWriter.size(); 59 uint32_t offset = fRestoreOffsetStack.top(); 60 while (offset) { 61 uint32_t* peek = fWriter.peek32(offset); 62 offset = *peek; 63 *peek = restoreOffset; 64 } 65 fRestoreOffsetStack.pop(); 66 67 addDraw(RESTORE); 68 validate(); 69 return this->INHERITED::restore(); 70} 71 72bool SkPictureRecord::translate(SkScalar dx, SkScalar dy) { 73 addDraw(TRANSLATE); 74 addScalar(dx); 75 addScalar(dy); 76 validate(); 77 return this->INHERITED::translate(dx, dy); 78} 79 80bool SkPictureRecord::scale(SkScalar sx, SkScalar sy) { 81 addDraw(SCALE); 82 addScalar(sx); 83 addScalar(sy); 84 validate(); 85 return this->INHERITED::scale(sx, sy); 86} 87 88bool SkPictureRecord::rotate(SkScalar degrees) { 89 addDraw(ROTATE); 90 addScalar(degrees); 91 validate(); 92 return this->INHERITED::rotate(degrees); 93} 94 95bool SkPictureRecord::skew(SkScalar sx, SkScalar sy) { 96 addDraw(SKEW); 97 addScalar(sx); 98 addScalar(sy); 99 validate(); 100 return this->INHERITED::skew(sx, sy); 101} 102 103bool SkPictureRecord::concat(const SkMatrix& matrix) { 104 validate(); 105 addDraw(CONCAT); 106 addMatrix(matrix); 107 validate(); 108 return this->INHERITED::concat(matrix); 109} 110 111void SkPictureRecord::setMatrix(const SkMatrix& matrix) { 112 validate(); 113 addDraw(SET_MATRIX); 114 addMatrix(matrix); 115 validate(); 116 this->INHERITED::setMatrix(matrix); 117} 118 119bool SkPictureRecord::clipRect(const SkRect& rect, SkRegion::Op op) { 120 addDraw(CLIP_RECT); 121 addRect(rect); 122 addInt(op); 123 124 size_t offset = fWriter.size(); 125 addInt(fRestoreOffsetStack.top()); 126 fRestoreOffsetStack.top() = offset; 127 128 validate(); 129 return this->INHERITED::clipRect(rect, op); 130} 131 132bool SkPictureRecord::clipPath(const SkPath& path, SkRegion::Op op) { 133 addDraw(CLIP_PATH); 134 addPath(path); 135 addInt(op); 136 137 size_t offset = fWriter.size(); 138 addInt(fRestoreOffsetStack.top()); 139 fRestoreOffsetStack.top() = offset; 140 141 validate(); 142 143 if (fRecordFlags & SkPicture::kUsePathBoundsForClip_RecordingFlag) { 144 return this->INHERITED::clipRect(path.getBounds(), op); 145 } else { 146 return this->INHERITED::clipPath(path, op); 147 } 148} 149 150bool SkPictureRecord::clipRegion(const SkRegion& region, SkRegion::Op op) { 151 addDraw(CLIP_REGION); 152 addRegion(region); 153 addInt(op); 154 155 size_t offset = fWriter.size(); 156 addInt(fRestoreOffsetStack.top()); 157 fRestoreOffsetStack.top() = offset; 158 159 validate(); 160 return this->INHERITED::clipRegion(region, op); 161} 162 163void SkPictureRecord::drawPaint(const SkPaint& paint) { 164 addDraw(DRAW_PAINT); 165 addPaint(paint); 166 validate(); 167} 168 169void SkPictureRecord::drawPoints(PointMode mode, size_t count, const SkPoint pts[], 170 const SkPaint& paint) { 171 addDraw(DRAW_POINTS); 172 addPaint(paint); 173 addInt(mode); 174 addInt(count); 175 fWriter.writeMul4(pts, count * sizeof(SkPoint)); 176 validate(); 177} 178 179void SkPictureRecord::drawRect(const SkRect& rect, const SkPaint& paint) { 180 addDraw(DRAW_RECT); 181 addPaint(paint); 182 addRect(rect); 183 validate(); 184} 185 186void SkPictureRecord::drawPath(const SkPath& path, const SkPaint& paint) { 187 addDraw(DRAW_PATH); 188 addPaint(paint); 189 addPath(path); 190 validate(); 191} 192 193void SkPictureRecord::drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top, 194 const SkPaint* paint = NULL) { 195 addDraw(DRAW_BITMAP); 196 addPaintPtr(paint); 197 addBitmap(bitmap); 198 addScalar(left); 199 addScalar(top); 200 validate(); 201} 202 203void SkPictureRecord::drawBitmapRect(const SkBitmap& bitmap, const SkIRect* src, 204 const SkRect& dst, const SkPaint* paint) { 205 addDraw(DRAW_BITMAP_RECT); 206 addPaintPtr(paint); 207 addBitmap(bitmap); 208 addIRectPtr(src); // may be null 209 addRect(dst); 210 validate(); 211} 212 213void SkPictureRecord::drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& matrix, 214 const SkPaint* paint) { 215 addDraw(DRAW_BITMAP_MATRIX); 216 addPaintPtr(paint); 217 addBitmap(bitmap); 218 addMatrix(matrix); 219 validate(); 220} 221 222void SkPictureRecord::drawSprite(const SkBitmap& bitmap, int left, int top, 223 const SkPaint* paint = NULL) { 224 addDraw(DRAW_SPRITE); 225 addPaintPtr(paint); 226 addBitmap(bitmap); 227 addInt(left); 228 addInt(top); 229 validate(); 230} 231 232void SkPictureRecord::addFontMetricsTopBottom(const SkPaint& paint, 233 SkScalar baselineY) { 234 SkPaint::FontMetrics metrics; 235 paint.getFontMetrics(&metrics); 236 SkRect bounds; 237 // construct a rect so we can see any adjustments from the paint. 238 // we use 0,1 for left,right, just so the rect isn't empty 239 bounds.set(0, metrics.fTop + baselineY, 240 SK_Scalar1, metrics.fBottom + baselineY); 241 (void)paint.computeFastBounds(bounds, &bounds); 242 // now record the top and bottom 243 addScalar(bounds.fTop); 244 addScalar(bounds.fBottom); 245} 246 247void SkPictureRecord::drawText(const void* text, size_t byteLength, SkScalar x, 248 SkScalar y, const SkPaint& paint) { 249 bool fast = paint.canComputeFastBounds(); 250 251 addDraw(fast ? DRAW_TEXT_TOP_BOTTOM : DRAW_TEXT); 252 addPaint(paint); 253 addText(text, byteLength); 254 addScalar(x); 255 addScalar(y); 256 if (fast) { 257 addFontMetricsTopBottom(paint, y); 258 } 259 validate(); 260} 261 262void SkPictureRecord::drawPosText(const void* text, size_t byteLength, 263 const SkPoint pos[], const SkPaint& paint) { 264 size_t points = paint.countText(text, byteLength); 265 if (0 == points) 266 return; 267 268 bool canUseDrawH = true; 269 // check if the caller really should have used drawPosTextH() 270 { 271 const SkScalar firstY = pos[0].fY; 272 for (size_t index = 1; index < points; index++) { 273 if (pos[index].fY != firstY) { 274 canUseDrawH = false; 275 break; 276 } 277 } 278 } 279 280 bool fast = canUseDrawH && paint.canComputeFastBounds(); 281 282 if (fast) { 283 addDraw(DRAW_POS_TEXT_H_TOP_BOTTOM); 284 } else { 285 addDraw(canUseDrawH ? DRAW_POS_TEXT_H : DRAW_POS_TEXT); 286 } 287 addPaint(paint); 288 addText(text, byteLength); 289 addInt(points); 290 291#ifdef SK_DEBUG_SIZE 292 size_t start = fWriter.size(); 293#endif 294 if (canUseDrawH) { 295 if (fast) { 296 addFontMetricsTopBottom(paint, pos[0].fY); 297 } 298 addScalar(pos[0].fY); 299 SkScalar* xptr = (SkScalar*)fWriter.reserve(points * sizeof(SkScalar)); 300 for (size_t index = 0; index < points; index++) 301 *xptr++ = pos[index].fX; 302 } 303 else { 304 fWriter.writeMul4(pos, points * sizeof(SkPoint)); 305 } 306#ifdef SK_DEBUG_SIZE 307 fPointBytes += fWriter.size() - start; 308 fPointWrites += points; 309#endif 310 validate(); 311} 312 313void SkPictureRecord::drawPosTextH(const void* text, size_t byteLength, 314 const SkScalar xpos[], SkScalar constY, 315 const SkPaint& paint) { 316 size_t points = paint.countText(text, byteLength); 317 if (0 == points) 318 return; 319 320 bool fast = paint.canComputeFastBounds(); 321 322 addDraw(fast ? DRAW_POS_TEXT_H_TOP_BOTTOM : DRAW_POS_TEXT_H); 323 addPaint(paint); 324 addText(text, byteLength); 325 addInt(points); 326 327#ifdef SK_DEBUG_SIZE 328 size_t start = fWriter.size(); 329#endif 330 if (fast) { 331 addFontMetricsTopBottom(paint, constY); 332 } 333 addScalar(constY); 334 fWriter.writeMul4(xpos, points * sizeof(SkScalar)); 335#ifdef SK_DEBUG_SIZE 336 fPointBytes += fWriter.size() - start; 337 fPointWrites += points; 338#endif 339 validate(); 340} 341 342void SkPictureRecord::drawTextOnPath(const void* text, size_t byteLength, 343 const SkPath& path, const SkMatrix* matrix, 344 const SkPaint& paint) { 345 addDraw(DRAW_TEXT_ON_PATH); 346 addPaint(paint); 347 addText(text, byteLength); 348 addPath(path); 349 addMatrixPtr(matrix); 350 validate(); 351} 352 353void SkPictureRecord::drawPicture(SkPicture& picture) { 354 addDraw(DRAW_PICTURE); 355 addPicture(picture); 356 validate(); 357} 358 359void SkPictureRecord::drawShape(SkShape* shape) { 360 addDraw(DRAW_SHAPE); 361 362 int index = fShapes.find(shape); 363 if (index < 0) { // not found 364 index = fShapes.count(); 365 *fShapes.append() = shape; 366 shape->ref(); 367 } 368 // follow the convention of recording a 1-based index 369 addInt(index + 1); 370 validate(); 371} 372 373void SkPictureRecord::drawVertices(VertexMode vmode, int vertexCount, 374 const SkPoint vertices[], const SkPoint texs[], 375 const SkColor colors[], SkXfermode*, 376 const uint16_t indices[], int indexCount, 377 const SkPaint& paint) { 378 uint32_t flags = 0; 379 if (texs) { 380 flags |= DRAW_VERTICES_HAS_TEXS; 381 } 382 if (colors) { 383 flags |= DRAW_VERTICES_HAS_COLORS; 384 } 385 if (indexCount > 0) { 386 flags |= DRAW_VERTICES_HAS_INDICES; 387 } 388 389 addDraw(DRAW_VERTICES); 390 addPaint(paint); 391 addInt(flags); 392 addInt(vmode); 393 addInt(vertexCount); 394 addPoints(vertices, vertexCount); 395 if (flags & DRAW_VERTICES_HAS_TEXS) { 396 addPoints(texs, vertexCount); 397 } 398 if (flags & DRAW_VERTICES_HAS_COLORS) { 399 fWriter.writeMul4(colors, vertexCount * sizeof(SkColor)); 400 } 401 if (flags & DRAW_VERTICES_HAS_INDICES) { 402 addInt(indexCount); 403 fWriter.writePad(indices, indexCount * sizeof(uint16_t)); 404 } 405} 406 407/////////////////////////////////////////////////////////////////////////////// 408 409void SkPictureRecord::reset() { 410 fPathHeap->safeUnref(); 411 fPathHeap = NULL; 412 413 fBitmaps.reset(); 414 fMatrices.reset(); 415 fPaints.reset(); 416 fPictureRefs.unrefAll(); 417 fRegions.reset(); 418 fShapes.safeUnrefAll(); 419 fWriter.reset(); 420 fHeap.reset(); 421 422 fRestoreOffsetStack.setCount(1); 423 fRestoreOffsetStack.top() = 0; 424 425 fRCRecorder.reset(); 426 fTFRecorder.reset(); 427} 428 429void SkPictureRecord::addBitmap(const SkBitmap& bitmap) { 430 addInt(find(fBitmaps, bitmap)); 431} 432 433void SkPictureRecord::addMatrix(const SkMatrix& matrix) { 434 addMatrixPtr(&matrix); 435} 436 437void SkPictureRecord::addMatrixPtr(const SkMatrix* matrix) { 438 addInt(find(fMatrices, matrix)); 439} 440 441void SkPictureRecord::addPaint(const SkPaint& paint) { 442 addPaintPtr(&paint); 443} 444 445void SkPictureRecord::addPaintPtr(const SkPaint* paint) { 446 addInt(find(fPaints, paint)); 447} 448 449void SkPictureRecord::addPath(const SkPath& path) { 450 if (NULL == fPathHeap) { 451 fPathHeap = SkNEW(SkPathHeap); 452 } 453 addInt(fPathHeap->append(path)); 454} 455 456void SkPictureRecord::addPicture(SkPicture& picture) { 457 int index = fPictureRefs.find(&picture); 458 if (index < 0) { // not found 459 index = fPictureRefs.count(); 460 *fPictureRefs.append() = &picture; 461 picture.ref(); 462 } 463 // follow the convention of recording a 1-based index 464 addInt(index + 1); 465} 466 467void SkPictureRecord::addPoint(const SkPoint& point) { 468#ifdef SK_DEBUG_SIZE 469 size_t start = fWriter.size(); 470#endif 471 fWriter.writePoint(point); 472#ifdef SK_DEBUG_SIZE 473 fPointBytes += fWriter.size() - start; 474 fPointWrites++; 475#endif 476} 477 478void SkPictureRecord::addPoints(const SkPoint pts[], int count) { 479 fWriter.writeMul4(pts, count * sizeof(SkPoint)); 480#ifdef SK_DEBUG_SIZE 481 fPointBytes += count * sizeof(SkPoint); 482 fPointWrites++; 483#endif 484} 485 486void SkPictureRecord::addRect(const SkRect& rect) { 487#ifdef SK_DEBUG_SIZE 488 size_t start = fWriter.size(); 489#endif 490 fWriter.writeRect(rect); 491#ifdef SK_DEBUG_SIZE 492 fRectBytes += fWriter.size() - start; 493 fRectWrites++; 494#endif 495} 496 497void SkPictureRecord::addRectPtr(const SkRect* rect) { 498 if (fWriter.writeBool(rect != NULL)) { 499 fWriter.writeRect(*rect); 500 } 501} 502 503void SkPictureRecord::addIRectPtr(const SkIRect* rect) { 504 if (fWriter.writeBool(rect != NULL)) { 505 *(SkIRect*)fWriter.reserve(sizeof(SkIRect)) = *rect; 506 } 507} 508 509void SkPictureRecord::addRegion(const SkRegion& region) { 510 addInt(find(fRegions, region)); 511} 512 513void SkPictureRecord::addText(const void* text, size_t byteLength) { 514#ifdef SK_DEBUG_SIZE 515 size_t start = fWriter.size(); 516#endif 517 addInt(byteLength); 518 fWriter.writePad(text, byteLength); 519#ifdef SK_DEBUG_SIZE 520 fTextBytes += fWriter.size() - start; 521 fTextWrites++; 522#endif 523} 524 525/////////////////////////////////////////////////////////////////////////////// 526 527int SkPictureRecord::find(SkTDArray<const SkFlatBitmap* >& bitmaps, const SkBitmap& bitmap) { 528 SkFlatBitmap* flat = SkFlatBitmap::Flatten(&fHeap, bitmap, fBitmapIndex, 529 &fRCRecorder); 530 int index = SkTSearch<SkFlatData>((const SkFlatData**) bitmaps.begin(), 531 bitmaps.count(), (SkFlatData*) flat, sizeof(flat), &SkFlatData::Compare); 532 if (index >= 0) { 533 (void)fHeap.unalloc(flat); 534 return bitmaps[index]->index(); 535 } 536 index = ~index; 537 *bitmaps.insert(index) = flat; 538 return fBitmapIndex++; 539} 540 541int SkPictureRecord::find(SkTDArray<const SkFlatMatrix* >& matrices, const SkMatrix* matrix) { 542 if (matrix == NULL) 543 return 0; 544 SkFlatMatrix* flat = SkFlatMatrix::Flatten(&fHeap, *matrix, fMatrixIndex); 545 int index = SkTSearch<SkFlatData>((const SkFlatData**) matrices.begin(), 546 matrices.count(), (SkFlatData*) flat, sizeof(flat), &SkFlatData::Compare); 547 if (index >= 0) { 548 (void)fHeap.unalloc(flat); 549 return matrices[index]->index(); 550 } 551 index = ~index; 552 *matrices.insert(index) = flat; 553 return fMatrixIndex++; 554} 555 556int SkPictureRecord::find(SkTDArray<const SkFlatPaint* >& paints, const SkPaint* paint) { 557 if (paint == NULL) { 558 return 0; 559 } 560 561 SkFlatPaint* flat = SkFlatPaint::Flatten(&fHeap, *paint, fPaintIndex, 562 &fRCRecorder, &fTFRecorder); 563 int index = SkTSearch<SkFlatData>((const SkFlatData**) paints.begin(), 564 paints.count(), (SkFlatData*) flat, sizeof(flat), &SkFlatData::Compare); 565 if (index >= 0) { 566 (void)fHeap.unalloc(flat); 567 return paints[index]->index(); 568 } 569 570 index = ~index; 571 *paints.insert(index) = flat; 572 return fPaintIndex++; 573} 574 575int SkPictureRecord::find(SkTDArray<const SkFlatRegion* >& regions, const SkRegion& region) { 576 SkFlatRegion* flat = SkFlatRegion::Flatten(&fHeap, region, fRegionIndex); 577 int index = SkTSearch<SkFlatData>((const SkFlatData**) regions.begin(), 578 regions.count(), (SkFlatData*) flat, sizeof(flat), &SkFlatData::Compare); 579 if (index >= 0) { 580 (void)fHeap.unalloc(flat); 581 return regions[index]->index(); 582 } 583 index = ~index; 584 *regions.insert(index) = flat; 585 return fRegionIndex++; 586} 587 588#ifdef SK_DEBUG_DUMP 589void SkPictureRecord::dumpMatrices() { 590 int count = fMatrices.count(); 591 SkMatrix defaultMatrix; 592 defaultMatrix.reset(); 593 for (int index = 0; index < count; index++) { 594 const SkFlatMatrix* flatMatrix = fMatrices[index]; 595 flatMatrix->dump(); 596 } 597} 598 599void SkPictureRecord::dumpPaints() { 600 int count = fPaints.count(); 601 for (int index = 0; index < count; index++) 602 fPaints[index]->dump(); 603} 604#endif 605 606#ifdef SK_DEBUG_SIZE 607size_t SkPictureRecord::size() const { 608 size_t result = 0; 609 size_t sizeData; 610 bitmaps(&sizeData); 611 result += sizeData; 612 matrices(&sizeData); 613 result += sizeData; 614 paints(&sizeData); 615 result += sizeData; 616 paths(&sizeData); 617 result += sizeData; 618 pictures(&sizeData); 619 result += sizeData; 620 regions(&sizeData); 621 result += sizeData; 622 result += streamlen(); 623 return result; 624} 625 626int SkPictureRecord::bitmaps(size_t* size) const { 627 size_t result = 0; 628 int count = fBitmaps.count(); 629 for (int index = 0; index < count; index++) 630 result += sizeof(fBitmaps[index]) + fBitmaps[index]->size(); 631 *size = result; 632 return count; 633} 634 635int SkPictureRecord::matrices(size_t* size) const { 636 int count = fMatrices.count(); 637 *size = sizeof(fMatrices[0]) * count; 638 return count; 639} 640 641int SkPictureRecord::paints(size_t* size) const { 642 size_t result = 0; 643 int count = fPaints.count(); 644 for (int index = 0; index < count; index++) 645 result += sizeof(fPaints[index]) + fPaints[index]->size(); 646 *size = result; 647 return count; 648} 649 650int SkPictureRecord::paths(size_t* size) const { 651 size_t result = 0; 652 int count = fPaths.count(); 653 for (int index = 0; index < count; index++) 654 result += sizeof(fPaths[index]) + fPaths[index]->size(); 655 *size = result; 656 return count; 657} 658 659int SkPictureRecord::regions(size_t* size) const { 660 size_t result = 0; 661 int count = fRegions.count(); 662 for (int index = 0; index < count; index++) 663 result += sizeof(fRegions[index]) + fRegions[index]->size(); 664 *size = result; 665 return count; 666} 667 668size_t SkPictureRecord::streamlen() const { 669 return fWriter.size(); 670} 671#endif 672 673#ifdef SK_DEBUG_VALIDATE 674void SkPictureRecord::validate() const { 675 validateBitmaps(); 676 validateMatrices(); 677 validatePaints(); 678 validatePaths(); 679 validatePictures(); 680 validateRegions(); 681} 682 683void SkPictureRecord::validateBitmaps() const { 684 int count = fBitmaps.count(); 685 SkASSERT((unsigned) count < 0x1000); 686 for (int index = 0; index < count; index++) { 687 const SkFlatBitmap* bitPtr = fBitmaps[index]; 688 SkASSERT(bitPtr); 689 bitPtr->validate(); 690 } 691} 692 693void SkPictureRecord::validateMatrices() const { 694 int count = fMatrices.count(); 695 SkASSERT((unsigned) count < 0x1000); 696 for (int index = 0; index < count; index++) { 697 const SkFlatMatrix* matrix = fMatrices[index]; 698 SkASSERT(matrix); 699 matrix->validate(); 700 } 701} 702 703void SkPictureRecord::validatePaints() const { 704 int count = fPaints.count(); 705 SkASSERT((unsigned) count < 0x1000); 706 for (int index = 0; index < count; index++) { 707 const SkFlatPaint* paint = fPaints[index]; 708 SkASSERT(paint); 709// paint->validate(); 710 } 711} 712 713void SkPictureRecord::validatePaths() const { 714 int count = fPaths.count(); 715 SkASSERT((unsigned) count < 0x1000); 716 for (int index = 0; index < count; index++) { 717 const SkFlatPath* path = fPaths[index]; 718 SkASSERT(path); 719 path->validate(); 720 } 721} 722 723void SkPictureRecord::validateRegions() const { 724 int count = fRegions.count(); 725 SkASSERT((unsigned) count < 0x1000); 726 for (int index = 0; index < count; index++) { 727 const SkFlatRegion* region = fRegions[index]; 728 SkASSERT(region); 729 region->validate(); 730 } 731} 732#endif 733 734