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 #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" |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
56 } | 56 } |
57 | 57 |
58 #undef SK_IGNORE_GPU_LAYER_HOISTING | 58 #undef SK_IGNORE_GPU_LAYER_HOISTING |
59 #define SK_IGNORE_GPU_LAYER_HOISTING 1 | 59 #define SK_IGNORE_GPU_LAYER_HOISTING 1 |
60 | 60 |
61 void SkMultiPictureDraw::draw() { | 61 void SkMultiPictureDraw::draw() { |
62 | 62 |
63 #ifndef SK_IGNORE_GPU_LAYER_HOISTING | 63 #ifndef SK_IGNORE_GPU_LAYER_HOISTING |
64 GrContext* context = NULL; | 64 GrContext* context = NULL; |
65 | 65 |
66 SkTDArray<GrHoistedLayer> atlased, nonAtlased, recycled; | 66 // 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 |
| 68 // drawing the canvas that requires them. |
| 69 SkTDArray<GrHoistedLayer> atlasedNeedRendering, atlasedRecycled; |
67 | 70 |
68 for (int i = 0; i < fDrawData.count(); ++i) { | 71 for (int i = 0; i < fDrawData.count(); ++i) { |
69 if (fDrawData[i].canvas->getGrContext() && | 72 if (fDrawData[i].canvas->getGrContext() && |
70 !fDrawData[i].paint && fDrawData[i].matrix.isIdentity()) { | 73 !fDrawData[i].paint && fDrawData[i].matrix.isIdentity()) { |
71 SkASSERT(NULL == context || context == fDrawData[i].canvas->getGrCon
text()); | 74 SkASSERT(NULL == context || context == fDrawData[i].canvas->getGrCon
text()); |
72 context = fDrawData[i].canvas->getGrContext(); | 75 context = fDrawData[i].canvas->getGrContext(); |
73 | 76 |
74 // TODO: this path always tries to optimize pictures. Should we | 77 // TODO: this path always tries to optimize pictures. Should we |
75 // switch to this API approach (vs. SkCanvas::EXPERIMENTAL_optimize)
? | 78 // switch to this API approach (vs. SkCanvas::EXPERIMENTAL_optimize)
? |
76 fDrawData[i].canvas->EXPERIMENTAL_optimize(fDrawData[i].picture); | 79 fDrawData[i].canvas->EXPERIMENTAL_optimize(fDrawData[i].picture); |
77 | 80 |
78 SkRect clipBounds; | 81 SkRect clipBounds; |
79 if (!fDrawData[i].canvas->getClipBounds(&clipBounds)) { | 82 if (!fDrawData[i].canvas->getClipBounds(&clipBounds)) { |
80 continue; | 83 continue; |
81 } | 84 } |
82 | 85 |
83 GrLayerHoister::FindLayersToHoist(context, fDrawData[i].picture, | 86 // TODO: sorting the cacheable layers from smallest to largest |
84 clipBounds, &atlased, &nonAtlased,
&recycled); | 87 // would improve the packing and reduce the number of swaps |
| 88 // TODO: another optimization would be to make a first pass to |
| 89 // lock any required layer that is already in the atlas |
| 90 GrLayerHoister::FindLayersToAtlas(context, fDrawData[i].picture, |
| 91 clipBounds, |
| 92 &atlasedNeedRendering, &atlasedRec
ycled); |
85 } | 93 } |
86 } | 94 } |
87 | 95 |
88 GrReplacements replacements; | 96 if (NULL != context) { |
| 97 GrLayerHoister::DrawLayersToAtlas(context, atlasedNeedRendering); |
| 98 } |
89 | 99 |
90 if (NULL != context) { | 100 SkTDArray<GrHoistedLayer> needRendering, recycled; |
91 GrLayerHoister::DrawLayers(atlased, nonAtlased, recycled, &replacements)
; | |
92 } | |
93 #endif | 101 #endif |
94 | 102 |
95 for (int i = 0; i < fDrawData.count(); ++i) { | 103 for (int i = 0; i < fDrawData.count(); ++i) { |
96 #ifndef SK_IGNORE_GPU_LAYER_HOISTING | 104 #ifndef SK_IGNORE_GPU_LAYER_HOISTING |
97 if (fDrawData[i].canvas->getGrContext() && | 105 if (fDrawData[i].canvas->getGrContext() && |
98 !fDrawData[i].paint && fDrawData[i].matrix.isIdentity()) { | 106 !fDrawData[i].paint && fDrawData[i].matrix.isIdentity()) { |
99 // Render the entire picture using new layers | 107 |
| 108 SkRect clipBounds; |
| 109 if (!fDrawData[i].canvas->getClipBounds(&clipBounds)) { |
| 110 continue; |
| 111 } |
| 112 |
| 113 // Find the layers required by this canvas. It will return atlased |
| 114 // layers in the 'recycled' list since they have already been drawn. |
| 115 GrLayerHoister::FindLayersToHoist(context, fDrawData[i].picture, |
| 116 clipBounds, &needRendering, &recyc
led); |
| 117 |
| 118 GrLayerHoister::DrawLayers(context, needRendering); |
| 119 |
| 120 GrReplacements replacements; |
| 121 |
| 122 GrLayerHoister::ConvertLayersToReplacements(needRendering, &replacem
ents); |
| 123 GrLayerHoister::ConvertLayersToReplacements(recycled, &replacements)
; |
| 124 |
100 const SkMatrix initialMatrix = fDrawData[i].canvas->getTotalMatrix()
; | 125 const SkMatrix initialMatrix = fDrawData[i].canvas->getTotalMatrix()
; |
101 | 126 |
| 127 // Render the entire picture using new layers |
102 GrRecordReplaceDraw(fDrawData[i].picture, fDrawData[i].canvas, | 128 GrRecordReplaceDraw(fDrawData[i].picture, fDrawData[i].canvas, |
103 &replacements, initialMatrix, NULL); | 129 &replacements, initialMatrix, NULL); |
104 } else | 130 |
| 131 GrLayerHoister::UnlockLayers(context, needRendering); |
| 132 GrLayerHoister::UnlockLayers(context, recycled); |
| 133 |
| 134 needRendering.rewind(); |
| 135 recycled.rewind(); |
| 136 } else |
105 #endif | 137 #endif |
106 { | 138 { |
107 fDrawData[i].canvas->drawPicture(fDrawData[i].picture, | 139 fDrawData[i].canvas->drawPicture(fDrawData[i].picture, |
108 &fDrawData[i].matrix, | 140 &fDrawData[i].matrix, |
109 fDrawData[i].paint); | 141 fDrawData[i].paint); |
110 } | 142 } |
111 } | 143 } |
112 | 144 |
113 #ifndef SK_IGNORE_GPU_LAYER_HOISTING | 145 #ifndef SK_IGNORE_GPU_LAYER_HOISTING |
114 if (NULL != context) { | 146 if (NULL != context) { |
115 GrLayerHoister::UnlockLayers(context, atlased, nonAtlased, recycled); | 147 GrLayerHoister::UnlockLayers(context, atlasedNeedRendering); |
| 148 GrLayerHoister::UnlockLayers(context, atlasedRecycled); |
116 } | 149 } |
117 #endif | 150 #endif |
118 | 151 |
119 this->reset(); | 152 this->reset(); |
120 } | 153 } |
121 | 154 |
OLD | NEW |