Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(59)

Side by Side Diff: src/core/SkMultiPictureDraw.cpp

Issue 684923002: MultiPictureDraw is taskgroup aware. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: actually call Reset() to free the data in each data Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « samplecode/SampleApp.cpp ('k') | src/core/SkTaskGroup.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 #if SK_SUPPORT_GPU 8 #if SK_SUPPORT_GPU
9 #include "GrLayerHoister.h" 9 #include "GrLayerHoister.h"
10 #include "GrRecordReplaceDraw.h" 10 #include "GrRecordReplaceDraw.h"
11 #endif 11 #endif
12 12
13 #include "SkCanvas.h" 13 #include "SkCanvas.h"
14 #include "SkMultiPictureDraw.h" 14 #include "SkMultiPictureDraw.h"
15 #include "SkPicture.h" 15 #include "SkPicture.h"
16 #include "SkTaskGroup.h"
17
18 void SkMultiPictureDraw::DrawData::draw() {
19 fCanvas->drawPicture(fPicture, &fMatrix, fPaint);
20 }
21
22 void SkMultiPictureDraw::DrawData::init(SkCanvas* canvas, const SkPicture* pictu re,
23 const SkMatrix* matrix, const SkPaint* p aint) {
24 fPicture = SkRef(picture);
25 fCanvas = SkRef(canvas);
26 if (matrix) {
27 fMatrix = *matrix;
28 } else {
29 fMatrix.setIdentity();
30 }
31 if (paint) {
32 fPaint = SkNEW_ARGS(SkPaint, (*paint));
33 } else {
34 fPaint = NULL;
35 }
36 }
37
38 void SkMultiPictureDraw::DrawData::Reset(SkTDArray<DrawData>& data) {
39 for (int i = 0; i < data.count(); ++i) {
40 data[i].fPicture->unref();
41 data[i].fCanvas->unref();
42 SkDELETE(data[i].fPaint);
43 }
44 data.rewind();
45 }
46
47 //////////////////////////////////////////////////////////////////////////////// //////
16 48
17 SkMultiPictureDraw::SkMultiPictureDraw(int reserve) { 49 SkMultiPictureDraw::SkMultiPictureDraw(int reserve) {
18 if (reserve > 0) { 50 if (reserve > 0) {
19 fDrawData.setReserve(reserve); 51 fGPUDrawData.setReserve(reserve);
52 fThreadSafeDrawData.setReserve(reserve);
20 } 53 }
21 } 54 }
22 55
23 void SkMultiPictureDraw::reset() { 56 void SkMultiPictureDraw::reset() {
24 for (int i = 0; i < fDrawData.count(); ++i) { 57 DrawData::Reset(fGPUDrawData);
25 fDrawData[i].picture->unref(); 58 DrawData::Reset(fThreadSafeDrawData);
26 fDrawData[i].canvas->unref();
27 SkDELETE(fDrawData[i].paint);
28 }
29
30 fDrawData.rewind();
31 } 59 }
32 60
33 void SkMultiPictureDraw::add(SkCanvas* canvas, 61 void SkMultiPictureDraw::add(SkCanvas* canvas,
34 const SkPicture* picture, 62 const SkPicture* picture,
35 const SkMatrix* matrix, 63 const SkMatrix* matrix,
36 const SkPaint* paint) { 64 const SkPaint* paint) {
37 if (NULL == canvas || NULL == picture) { 65 if (NULL == canvas || NULL == picture) {
38 SkDEBUGFAIL("parameters to SkMultiPictureDraw::add should be non-NULL"); 66 SkDEBUGFAIL("parameters to SkMultiPictureDraw::add should be non-NULL");
39 return; 67 return;
40 } 68 }
41 69
42 DrawData* data = fDrawData.append(); 70 SkTDArray<DrawData>& array = canvas->getGrContext() ? fGPUDrawData : fThread SafeDrawData;
43 71 array.append()->init(canvas, picture, matrix, paint);
44 data->picture = SkRef(picture);
45 data->canvas = SkRef(canvas);
46 if (matrix) {
47 data->matrix = *matrix;
48 } else {
49 data->matrix.setIdentity();
50 }
51 if (paint) {
52 data->paint = SkNEW_ARGS(SkPaint, (*paint));
53 } else {
54 data->paint = NULL;
55 }
56 } 72 }
57 73
58 #undef SK_IGNORE_GPU_LAYER_HOISTING 74 #undef SK_IGNORE_GPU_LAYER_HOISTING
59 #define SK_IGNORE_GPU_LAYER_HOISTING 1 75 #define SK_IGNORE_GPU_LAYER_HOISTING 1
60 76
77 class AutoMPDReset : SkNoncopyable {
78 SkMultiPictureDraw* fMPD;
79 public:
80 AutoMPDReset(SkMultiPictureDraw* mpd) : fMPD(mpd) {}
81 ~AutoMPDReset() { fMPD->reset(); }
82 };
83
61 void SkMultiPictureDraw::draw() { 84 void SkMultiPictureDraw::draw() {
85 AutoMPDReset mpdreset(this);
86 // we place the taskgroup after the MPDReset, to ensure that we don't delete the DrawData
87 // objects until after we're finished the tasks (which have pointers to the data).
88
89 SkTaskGroup group;
90 for (int i = 0; i < fThreadSafeDrawData.count(); ++i) {
91 group.add(DrawData::Run, &fThreadSafeDrawData[i]);
92 }
93 // we deliberately don't call wait() here, since the destructor will do that , this allows us
94 // to continue processing gpu-data without having to wait on the cpu tasks.
95
96 const int count = fGPUDrawData.count();
97 if (0 == count) {
98 return;
99 }
62 100
63 #ifndef SK_IGNORE_GPU_LAYER_HOISTING 101 #ifndef SK_IGNORE_GPU_LAYER_HOISTING
64 GrContext* context = NULL; 102 GrContext* context = fGPUDrawData[0].fCanvas->getGrContext();
103 SkASSERT(context);
65 104
66 // Start by collecting all the layers that are going to be atlased and rende r 105 // Start by collecting all the layers that are going to be atlased and rende r
67 // them (if necessary). Hoisting the free floating layers is deferred until 106 // them (if necessary). Hoisting the free floating layers is deferred until
68 // drawing the canvas that requires them. 107 // drawing the canvas that requires them.
69 SkTDArray<GrHoistedLayer> atlasedNeedRendering, atlasedRecycled; 108 SkTDArray<GrHoistedLayer> atlasedNeedRendering, atlasedRecycled;
70 109
71 for (int i = 0; i < fDrawData.count(); ++i) { 110 for (int i = 0; i < count; ++i) {
72 if (fDrawData[i].canvas->getGrContext() && 111 const DrawData& data = fGPUDrawData[i];
73 !fDrawData[i].paint && fDrawData[i].matrix.isIdentity()) { 112 // we only expect 1 context for all the canvases
74 SkASSERT(NULL == context || context == fDrawData[i].canvas->getGrCon text()); 113 SkASSERT(data.canvas->getGrContext() == context);
75 context = fDrawData[i].canvas->getGrContext();
76 114
115 if (!data.fPaint && data.fMatrix.isIdentity()) {
77 // TODO: this path always tries to optimize pictures. Should we 116 // TODO: this path always tries to optimize pictures. Should we
78 // switch to this API approach (vs. SkCanvas::EXPERIMENTAL_optimize) ? 117 // switch to this API approach (vs. SkCanvas::EXPERIMENTAL_optimize) ?
79 fDrawData[i].canvas->EXPERIMENTAL_optimize(fDrawData[i].picture); 118 data.fCanvas->EXPERIMENTAL_optimize(data.fPicture);
80 119
81 SkRect clipBounds; 120 SkRect clipBounds;
82 if (!fDrawData[i].canvas->getClipBounds(&clipBounds)) { 121 if (!data.fCanvas->getClipBounds(&clipBounds)) {
83 continue; 122 continue;
84 } 123 }
85 124
86 // TODO: sorting the cacheable layers from smallest to largest 125 // TODO: sorting the cacheable layers from smallest to largest
87 // would improve the packing and reduce the number of swaps 126 // would improve the packing and reduce the number of swaps
88 // TODO: another optimization would be to make a first pass to 127 // TODO: another optimization would be to make a first pass to
89 // lock any required layer that is already in the atlas 128 // lock any required layer that is already in the atlas
90 GrLayerHoister::FindLayersToAtlas(context, fDrawData[i].picture, 129 GrLayerHoister::FindLayersToAtlas(context, data.fPicture,
91 clipBounds, 130 clipBounds,
92 &atlasedNeedRendering, &atlasedRec ycled); 131 &atlasedNeedRendering, &atlasedRec ycled);
93 } 132 }
94 } 133 }
95 134
96 if (NULL != context) { 135 GrLayerHoister::DrawLayersToAtlas(context, atlasedNeedRendering);
97 GrLayerHoister::DrawLayersToAtlas(context, atlasedNeedRendering);
98 }
99 136
100 SkTDArray<GrHoistedLayer> needRendering, recycled; 137 SkTDArray<GrHoistedLayer> needRendering, recycled;
101 #endif 138 #endif
102 139
103 for (int i = 0; i < fDrawData.count(); ++i) { 140 for (int i = 0; i < count; ++i) {
141 const DrawData& data = fGPUDrawData[i];
142 SkCanvas* canvas = data.fCanvas;
143 const SkPicture* picture = data.fPicture;
144
104 #ifndef SK_IGNORE_GPU_LAYER_HOISTING 145 #ifndef SK_IGNORE_GPU_LAYER_HOISTING
105 if (fDrawData[i].canvas->getGrContext() && 146 if (!data.fPaint && data.fMatrix.isIdentity()) {
106 !fDrawData[i].paint && fDrawData[i].matrix.isIdentity()) {
107 147
108 SkRect clipBounds; 148 SkRect clipBounds;
109 if (!fDrawData[i].canvas->getClipBounds(&clipBounds)) { 149 if (!canvas->getClipBounds(&clipBounds)) {
110 continue; 150 continue;
111 } 151 }
112 152
113 // Find the layers required by this canvas. It will return atlased 153 // Find the layers required by this canvas. It will return atlased
114 // layers in the 'recycled' list since they have already been drawn. 154 // layers in the 'recycled' list since they have already been drawn.
115 GrLayerHoister::FindLayersToHoist(context, fDrawData[i].picture, 155 GrLayerHoister::FindLayersToHoist(context, picture,
116 clipBounds, &needRendering, &recyc led); 156 clipBounds, &needRendering, &recyc led);
117 157
118 GrLayerHoister::DrawLayers(context, needRendering); 158 GrLayerHoister::DrawLayers(context, needRendering);
119 159
120 GrReplacements replacements; 160 GrReplacements replacements;
121 161
122 GrLayerHoister::ConvertLayersToReplacements(needRendering, &replacem ents); 162 GrLayerHoister::ConvertLayersToReplacements(needRendering, &replacem ents);
123 GrLayerHoister::ConvertLayersToReplacements(recycled, &replacements) ; 163 GrLayerHoister::ConvertLayersToReplacements(recycled, &replacements) ;
124 164
125 const SkMatrix initialMatrix = fDrawData[i].canvas->getTotalMatrix() ; 165 const SkMatrix initialMatrix = canvas->getTotalMatrix();
126 166
127 // Render the entire picture using new layers 167 // Render the entire picture using new layers
128 GrRecordReplaceDraw(fDrawData[i].picture, fDrawData[i].canvas, 168 GrRecordReplaceDraw(picture, canvas, &replacements, initialMatrix, N ULL);
129 &replacements, initialMatrix, NULL);
130 169
131 GrLayerHoister::UnlockLayers(context, needRendering); 170 GrLayerHoister::UnlockLayers(context, needRendering);
132 GrLayerHoister::UnlockLayers(context, recycled); 171 GrLayerHoister::UnlockLayers(context, recycled);
133 172
134 needRendering.rewind(); 173 needRendering.rewind();
135 recycled.rewind(); 174 recycled.rewind();
136 } else 175 } else
137 #endif 176 #endif
138 { 177 {
139 fDrawData[i].canvas->drawPicture(fDrawData[i].picture, 178 canvas->drawPicture(picture, &data.fMatrix, data.fPaint);
140 &fDrawData[i].matrix,
141 fDrawData[i].paint);
142 } 179 }
143 } 180 }
144 181
145 #ifndef SK_IGNORE_GPU_LAYER_HOISTING 182 #ifndef SK_IGNORE_GPU_LAYER_HOISTING
146 if (NULL != context) { 183 GrLayerHoister::UnlockLayers(context, atlasedNeedRendering);
147 GrLayerHoister::UnlockLayers(context, atlasedNeedRendering); 184 GrLayerHoister::UnlockLayers(context, atlasedRecycled);
148 GrLayerHoister::UnlockLayers(context, atlasedRecycled);
149 }
150 #endif 185 #endif
151
152 this->reset();
153 } 186 }
154 187
OLDNEW
« no previous file with comments | « samplecode/SampleApp.cpp ('k') | src/core/SkTaskGroup.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698