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* 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, SkCanvas* canvas, |
58 SkCanvas* canvas, | 59 SkPicture const* const drawablePicts[], int drawableCou
nt, |
59 const SkRect& clearRect, | 60 const SkRect& clearRect, |
60 unsigned start, unsigned stop, | 61 unsigned start, unsigned stop, |
61 const SkMatrix& initialCTM) { | 62 const SkMatrix& initialCTM) { |
62 SkAutoCanvasRestore saveRestore(canvas, true /*save now, restore at exit*/); | 63 SkAutoCanvasRestore saveRestore(canvas, true /*save now, restore at exit*/); |
63 | 64 |
64 stop = SkTMin(stop, record.count()); | 65 stop = SkTMin(stop, record.count()); |
65 SkRecords::PartialDraw draw(canvas, clearRect, initialCTM); | 66 SkRecords::PartialDraw draw(canvas, NULL, 0, clearRect, initialCTM); |
66 for (unsigned i = start; i < stop; i++) { | 67 for (unsigned i = start; i < stop; i++) { |
67 record.visit<void>(i, draw); | 68 record.visit<void>(i, draw); |
68 } | 69 } |
69 } | 70 } |
70 | 71 |
71 namespace SkRecords { | 72 namespace SkRecords { |
72 | 73 |
73 // FIXME: SkBitmaps are stateful, so we need to copy them to play back in multip
le threads. | 74 // 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) { | 75 static SkBitmap shallow_copy(const SkBitmap& bitmap) { |
75 return bitmap; | 76 return bitmap; |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
116 DRAW(DrawRect, drawRect(r.rect, r.paint)); | 117 DRAW(DrawRect, drawRect(r.rect, r.paint)); |
117 DRAW(DrawSprite, drawSprite(shallow_copy(r.bitmap), r.left, r.top, r.paint)); | 118 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)); | 119 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)); | 120 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)); | 121 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, | 122 DRAW(DrawVertices, drawVertices(r.vmode, r.vertexCount, r.vertices, r.texs, r.co
lors, |
122 r.xmode.get(), r.indices, r.indexCount, r.paint)
); | 123 r.xmode.get(), r.indices, r.indexCount, r.paint)
); |
123 DRAW(DrawData, drawData(r.data, r.length)); | 124 DRAW(DrawData, drawData(r.data, r.length)); |
124 #undef DRAW | 125 #undef DRAW |
125 | 126 |
| 127 template <> void Draw::draw(const DrawDrawable& r) { |
| 128 SkASSERT(r.index >= 0); |
| 129 SkASSERT(r.index < fDrawableCount); |
| 130 fCanvas->drawPicture(fDrawablePicts[r.index]); |
| 131 } |
| 132 |
126 // This is an SkRecord visitor that fills an SkBBoxHierarchy. | 133 // This is an SkRecord visitor that fills an SkBBoxHierarchy. |
127 // | 134 // |
128 // The interesting part here is how to calculate bounds for ops which don't | 135 // 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? | 136 // have intrinsic bounds. What is the bounds of a Save or a Translate? |
130 // | 137 // |
131 // We answer this by thinking about a particular definition of bounds: if I | 138 // 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 | 139 // 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 | 140 // 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 | 141 // 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 | 142 // 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 | 502 |
496 return this->adjustAndMap(dst, &op.paint); | 503 return this->adjustAndMap(dst, &op.paint); |
497 } | 504 } |
498 | 505 |
499 Bounds bounds(const DrawTextBlob& op) const { | 506 Bounds bounds(const DrawTextBlob& op) const { |
500 SkRect dst = op.blob->bounds(); | 507 SkRect dst = op.blob->bounds(); |
501 dst.offset(op.x, op.y); | 508 dst.offset(op.x, op.y); |
502 return this->adjustAndMap(dst, &op.paint); | 509 return this->adjustAndMap(dst, &op.paint); |
503 } | 510 } |
504 | 511 |
| 512 Bounds bounds(const DrawDrawable& op) const { |
| 513 return this->adjustAndMap(op.worstCaseBounds, NULL); |
| 514 } |
| 515 |
505 static void AdjustTextForFontMetrics(SkRect* rect, const SkPaint& paint) { | 516 static void AdjustTextForFontMetrics(SkRect* rect, const SkPaint& paint) { |
506 #ifdef SK_DEBUG | 517 #ifdef SK_DEBUG |
507 SkRect correct = *rect; | 518 SkRect correct = *rect; |
508 #endif | 519 #endif |
509 // crbug.com/373785 ~~> xPad = 4x yPad | 520 // crbug.com/373785 ~~> xPad = 4x yPad |
510 // crbug.com/424824 ~~> bump yPad from 2x text size to 2.5x | 521 // crbug.com/424824 ~~> bump yPad from 2x text size to 2.5x |
511 const SkScalar yPad = 2.5f * paint.getTextSize(), | 522 const SkScalar yPad = 2.5f * paint.getTextSize(), |
512 xPad = 4.0f * yPad; | 523 xPad = 4.0f * yPad; |
513 rect->outset(xPad, yPad); | 524 rect->outset(xPad, yPad); |
514 #ifdef SK_DEBUG | 525 #ifdef SK_DEBUG |
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
745 SkRecords::CollectLayers visitor(cullRect, record, data); | 756 SkRecords::CollectLayers visitor(cullRect, record, data); |
746 | 757 |
747 for (unsigned curOp = 0; curOp < record.count(); curOp++) { | 758 for (unsigned curOp = 0; curOp < record.count(); curOp++) { |
748 visitor.setCurrentOp(curOp); | 759 visitor.setCurrentOp(curOp); |
749 record.visit<void>(curOp, visitor); | 760 record.visit<void>(curOp, visitor); |
750 } | 761 } |
751 | 762 |
752 visitor.cleanUp(bbh); | 763 visitor.cleanUp(bbh); |
753 } | 764 } |
754 | 765 |
OLD | NEW |