OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkLayerInfo.h" | 8 #include "SkLayerInfo.h" |
9 #include "SkRecordDraw.h" | 9 #include "SkRecordDraw.h" |
10 #include "SkPatchUtils.h" | 10 #include "SkPatchUtils.h" |
11 | 11 |
12 void SkRecordDraw(const SkRecord& record, | 12 void SkRecordDraw(const SkRecord& record, |
13 SkCanvas* canvas, | 13 SkCanvas* canvas, |
| 14 SkPicture* const drawablePicts[], int drawableCount, |
14 const SkBBoxHierarchy* bbh, | 15 const SkBBoxHierarchy* bbh, |
15 SkDrawPictureCallback* callback) { | 16 SkDrawPictureCallback* callback) { |
16 SkAutoCanvasRestore saveRestore(canvas, true /*save now, restore at exit*/); | 17 SkAutoCanvasRestore saveRestore(canvas, true /*save now, restore at exit*/); |
17 | 18 |
18 if (bbh) { | 19 if (bbh) { |
19 // Draw only ops that affect pixels in the canvas's current clip. | 20 // Draw only ops that affect pixels in the canvas's current clip. |
20 // The SkRecord and BBH were recorded in identity space. This canvas | 21 // The SkRecord and BBH were recorded in identity space. This canvas |
21 // is not necessarily in that same space. getClipBounds() returns us | 22 // is not necessarily in that same space. getClipBounds() returns us |
22 // this canvas' clip bounds transformed back into identity space, which | 23 // this canvas' clip bounds transformed back into identity space, which |
23 // lets us query the BBH. | 24 // lets us query the BBH. |
24 SkRect query; | 25 SkRect query; |
25 if (!canvas->getClipBounds(&query)) { | 26 if (!canvas->getClipBounds(&query)) { |
26 return; | 27 return; |
27 } | 28 } |
28 | 29 |
29 SkTDArray<unsigned> ops; | 30 SkTDArray<unsigned> ops; |
30 bbh->search(query, &ops); | 31 bbh->search(query, &ops); |
31 | 32 |
32 SkRecords::Draw draw(canvas); | 33 SkRecords::Draw draw(canvas, drawablePicts, drawableCount); |
33 for (int i = 0; i < ops.count(); i++) { | 34 for (int i = 0; i < ops.count(); i++) { |
34 if (callback && callback->abortDrawing()) { | 35 if (callback && callback->abortDrawing()) { |
35 return; | 36 return; |
36 } | 37 } |
37 // This visit call uses the SkRecords::Draw::operator() to call | 38 // This visit call uses the SkRecords::Draw::operator() to call |
38 // methods on the |canvas|, wrapped by methods defined with the | 39 // methods on the |canvas|, wrapped by methods defined with the |
39 // DRAW() macro. | 40 // DRAW() macro. |
40 record.visit<void>(ops[i], draw); | 41 record.visit<void>(ops[i], draw); |
41 } | 42 } |
42 } else { | 43 } else { |
43 // Draw all ops. | 44 // Draw all ops. |
44 SkRecords::Draw draw(canvas); | 45 SkRecords::Draw draw(canvas, drawablePicts, drawableCount); |
45 for (unsigned i = 0; i < record.count(); i++) { | 46 for (unsigned i = 0; i < record.count(); i++) { |
46 if (callback && callback->abortDrawing()) { | 47 if (callback && callback->abortDrawing()) { |
47 return; | 48 return; |
48 } | 49 } |
49 // This visit call uses the SkRecords::Draw::operator() to call | 50 // This visit call uses the SkRecords::Draw::operator() to call |
50 // methods on the |canvas|, wrapped by methods defined with the | 51 // methods on the |canvas|, wrapped by methods defined with the |
51 // DRAW() macro. | 52 // DRAW() macro. |
52 record.visit<void>(i, draw); | 53 record.visit<void>(i, draw); |
53 } | 54 } |
54 } | 55 } |
55 } | 56 } |
56 | 57 |
57 void SkRecordPartialDraw(const SkRecord& record, | 58 void SkRecordPartialDraw(const SkRecord& record, |
58 SkCanvas* canvas, | 59 SkCanvas* canvas, |
| 60 // SkPicture* const drawablePicts[], int drawableCount, |
59 const SkRect& clearRect, | 61 const SkRect& clearRect, |
60 unsigned start, unsigned stop, | 62 unsigned start, unsigned stop, |
61 const SkMatrix& initialCTM) { | 63 const SkMatrix& initialCTM) { |
62 SkAutoCanvasRestore saveRestore(canvas, true /*save now, restore at exit*/); | 64 SkAutoCanvasRestore saveRestore(canvas, true /*save now, restore at exit*/); |
63 | 65 |
64 stop = SkTMin(stop, record.count()); | 66 stop = SkTMin(stop, record.count()); |
65 SkRecords::PartialDraw draw(canvas, clearRect, initialCTM); | 67 SkRecords::PartialDraw draw(canvas, NULL, 0, clearRect, initialCTM); |
66 for (unsigned i = start; i < stop; i++) { | 68 for (unsigned i = start; i < stop; i++) { |
67 record.visit<void>(i, draw); | 69 record.visit<void>(i, draw); |
68 } | 70 } |
69 } | 71 } |
70 | 72 |
71 namespace SkRecords { | 73 namespace SkRecords { |
72 | 74 |
73 // FIXME: SkBitmaps are stateful, so we need to copy them to play back in multip
le threads. | 75 // FIXME: SkBitmaps are stateful, so we need to copy them to play back in multip
le threads. |
74 static SkBitmap shallow_copy(const SkBitmap& bitmap) { | 76 static SkBitmap shallow_copy(const SkBitmap& bitmap) { |
75 return bitmap; | 77 return bitmap; |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
116 DRAW(DrawRect, drawRect(r.rect, r.paint)); | 118 DRAW(DrawRect, drawRect(r.rect, r.paint)); |
117 DRAW(DrawSprite, drawSprite(shallow_copy(r.bitmap), r.left, r.top, r.paint)); | 119 DRAW(DrawSprite, drawSprite(shallow_copy(r.bitmap), r.left, r.top, r.paint)); |
118 DRAW(DrawText, drawText(r.text, r.byteLength, r.x, r.y, r.paint)); | 120 DRAW(DrawText, drawText(r.text, r.byteLength, r.x, r.y, r.paint)); |
119 DRAW(DrawTextBlob, drawTextBlob(r.blob, r.x, r.y, r.paint)); | 121 DRAW(DrawTextBlob, drawTextBlob(r.blob, r.x, r.y, r.paint)); |
120 DRAW(DrawTextOnPath, drawTextOnPath(r.text, r.byteLength, r.path, r.matrix, r.pa
int)); | 122 DRAW(DrawTextOnPath, drawTextOnPath(r.text, r.byteLength, r.path, r.matrix, r.pa
int)); |
121 DRAW(DrawVertices, drawVertices(r.vmode, r.vertexCount, r.vertices, r.texs, r.co
lors, | 123 DRAW(DrawVertices, drawVertices(r.vmode, r.vertexCount, r.vertices, r.texs, r.co
lors, |
122 r.xmode.get(), r.indices, r.indexCount, r.paint)
); | 124 r.xmode.get(), r.indices, r.indexCount, r.paint)
); |
123 DRAW(DrawData, drawData(r.data, r.length)); | 125 DRAW(DrawData, drawData(r.data, r.length)); |
124 #undef DRAW | 126 #undef DRAW |
125 | 127 |
| 128 template <> void Draw::draw(const DrawDrawable& r) { |
| 129 SkASSERT(r.index >= 0); |
| 130 SkASSERT(r.index < fDrawableCount); |
| 131 fCanvas->drawPicture(fDrawablePicts[r.index]); |
| 132 } |
| 133 |
126 // This is an SkRecord visitor that fills an SkBBoxHierarchy. | 134 // This is an SkRecord visitor that fills an SkBBoxHierarchy. |
127 // | 135 // |
128 // The interesting part here is how to calculate bounds for ops which don't | 136 // The interesting part here is how to calculate bounds for ops which don't |
129 // have intrinsic bounds. What is the bounds of a Save or a Translate? | 137 // have intrinsic bounds. What is the bounds of a Save or a Translate? |
130 // | 138 // |
131 // We answer this by thinking about a particular definition of bounds: if I | 139 // We answer this by thinking about a particular definition of bounds: if I |
132 // don't execute this op, pixels in this rectangle might draw incorrectly. So | 140 // don't execute this op, pixels in this rectangle might draw incorrectly. So |
133 // the bounds of a Save, a Translate, a Restore, etc. are the union of the | 141 // the bounds of a Save, a Translate, a Restore, etc. are the union of the |
134 // bounds of Draw* ops that they might have an effect on. For any given | 142 // bounds of Draw* ops that they might have an effect on. For any given |
135 // Save/Restore block, the bounds of the Save, the Restore, and any other | 143 // Save/Restore block, the bounds of the Save, the Restore, and any other |
(...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
495 | 503 |
496 return this->adjustAndMap(dst, &op.paint); | 504 return this->adjustAndMap(dst, &op.paint); |
497 } | 505 } |
498 | 506 |
499 Bounds bounds(const DrawTextBlob& op) const { | 507 Bounds bounds(const DrawTextBlob& op) const { |
500 SkRect dst = op.blob->bounds(); | 508 SkRect dst = op.blob->bounds(); |
501 dst.offset(op.x, op.y); | 509 dst.offset(op.x, op.y); |
502 return this->adjustAndMap(dst, &op.paint); | 510 return this->adjustAndMap(dst, &op.paint); |
503 } | 511 } |
504 | 512 |
| 513 Bounds bounds(const DrawDrawable& op) const { |
| 514 return this->adjustAndMap(op.worstCaseBounds, NULL); |
| 515 } |
| 516 |
505 static void AdjustTextForFontMetrics(SkRect* rect, const SkPaint& paint) { | 517 static void AdjustTextForFontMetrics(SkRect* rect, const SkPaint& paint) { |
506 #ifdef SK_DEBUG | 518 #ifdef SK_DEBUG |
507 SkRect correct = *rect; | 519 SkRect correct = *rect; |
508 #endif | 520 #endif |
509 // crbug.com/373785 ~~> xPad = 4x yPad | 521 // crbug.com/373785 ~~> xPad = 4x yPad |
510 // crbug.com/424824 ~~> bump yPad from 2x text size to 2.5x | 522 // crbug.com/424824 ~~> bump yPad from 2x text size to 2.5x |
511 const SkScalar yPad = 2.5f * paint.getTextSize(), | 523 const SkScalar yPad = 2.5f * paint.getTextSize(), |
512 xPad = 4.0f * yPad; | 524 xPad = 4.0f * yPad; |
513 rect->outset(xPad, yPad); | 525 rect->outset(xPad, yPad); |
514 #ifdef SK_DEBUG | 526 #ifdef SK_DEBUG |
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
745 SkRecords::CollectLayers visitor(cullRect, record, data); | 757 SkRecords::CollectLayers visitor(cullRect, record, data); |
746 | 758 |
747 for (unsigned curOp = 0; curOp < record.count(); curOp++) { | 759 for (unsigned curOp = 0; curOp < record.count(); curOp++) { |
748 visitor.setCurrentOp(curOp); | 760 visitor.setCurrentOp(curOp); |
749 record.visit<void>(curOp, visitor); | 761 record.visit<void>(curOp, visitor); |
750 } | 762 } |
751 | 763 |
752 visitor.cleanUp(bbh); | 764 visitor.cleanUp(bbh); |
753 } | 765 } |
754 | 766 |
OLD | NEW |