Line data Source code
1 : /*
2 : * Copyright 2014 Google Inc.
3 : *
4 : * Use of this source code is governed by a BSD-style license that can be
5 : * found in the LICENSE file.
6 : */
7 :
8 : #include "SkCanvas.h"
9 : #include "SkCanvasPriv.h"
10 : #include "SkMultiPictureDraw.h"
11 : #include "SkPicture.h"
12 : #include "SkTaskGroup.h"
13 :
14 0 : void SkMultiPictureDraw::DrawData::draw() {
15 0 : fCanvas->drawPicture(fPicture, &fMatrix, fPaint);
16 0 : }
17 :
18 0 : void SkMultiPictureDraw::DrawData::init(SkCanvas* canvas, const SkPicture* picture,
19 : const SkMatrix* matrix, const SkPaint* paint) {
20 0 : fPicture = SkRef(picture);
21 0 : fCanvas = canvas;
22 0 : if (matrix) {
23 0 : fMatrix = *matrix;
24 : } else {
25 0 : fMatrix.setIdentity();
26 : }
27 0 : if (paint) {
28 0 : fPaint = new SkPaint(*paint);
29 : } else {
30 0 : fPaint = nullptr;
31 : }
32 0 : }
33 :
34 0 : void SkMultiPictureDraw::DrawData::Reset(SkTDArray<DrawData>& data) {
35 0 : for (int i = 0; i < data.count(); ++i) {
36 0 : data[i].fPicture->unref();
37 0 : delete data[i].fPaint;
38 : }
39 0 : data.rewind();
40 0 : }
41 :
42 : //////////////////////////////////////////////////////////////////////////////////////
43 :
44 0 : SkMultiPictureDraw::SkMultiPictureDraw(int reserve) {
45 0 : if (reserve > 0) {
46 0 : fGPUDrawData.setReserve(reserve);
47 0 : fThreadSafeDrawData.setReserve(reserve);
48 : }
49 0 : }
50 :
51 0 : void SkMultiPictureDraw::reset() {
52 0 : DrawData::Reset(fGPUDrawData);
53 0 : DrawData::Reset(fThreadSafeDrawData);
54 0 : }
55 :
56 0 : void SkMultiPictureDraw::add(SkCanvas* canvas,
57 : const SkPicture* picture,
58 : const SkMatrix* matrix,
59 : const SkPaint* paint) {
60 0 : if (nullptr == canvas || nullptr == picture) {
61 0 : SkDEBUGFAIL("parameters to SkMultiPictureDraw::add should be non-nullptr");
62 0 : return;
63 : }
64 :
65 0 : SkTDArray<DrawData>& array = canvas->getGrContext() ? fGPUDrawData : fThreadSafeDrawData;
66 0 : array.append()->init(canvas, picture, matrix, paint);
67 : }
68 :
69 : class AutoMPDReset : SkNoncopyable {
70 : SkMultiPictureDraw* fMPD;
71 : public:
72 0 : AutoMPDReset(SkMultiPictureDraw* mpd) : fMPD(mpd) {}
73 0 : ~AutoMPDReset() { fMPD->reset(); }
74 : };
75 :
76 : //#define FORCE_SINGLE_THREAD_DRAWING_FOR_TESTING
77 :
78 0 : void SkMultiPictureDraw::draw(bool flush) {
79 0 : AutoMPDReset mpdreset(this);
80 :
81 : #ifdef FORCE_SINGLE_THREAD_DRAWING_FOR_TESTING
82 : for (int i = 0; i < fThreadSafeDrawData.count(); ++i) {
83 : fThreadSafeDrawData[i].draw();
84 : }
85 : #else
86 0 : SkTaskGroup().batch(fThreadSafeDrawData.count(), [&](int i) {
87 0 : fThreadSafeDrawData[i].draw();
88 0 : });
89 : #endif
90 :
91 : // N.B. we could get going on any GPU work from this main thread while the CPU work runs.
92 : // But in practice, we've either got GPU work or CPU work, not both.
93 :
94 0 : const int count = fGPUDrawData.count();
95 0 : if (0 == count) {
96 0 : return;
97 : }
98 :
99 0 : for (int i = 0; i < count; ++i) {
100 0 : const DrawData& data = fGPUDrawData[i];
101 0 : SkCanvas* canvas = data.fCanvas;
102 0 : const SkPicture* picture = data.fPicture;
103 :
104 0 : canvas->drawPicture(picture, &data.fMatrix, data.fPaint);
105 0 : if (flush) {
106 0 : canvas->flush();
107 : }
108 : }
109 : }
|