Changeset View
Standalone View
scene.cpp
Show First 20 Lines • Show All 134 Lines • ▼ Show 20 Line(s) | 133 | } else if (*mask & PAINT_SCREEN_REGION) { | |||
---|---|---|---|---|---|
135 | region &= displayRegion; | 135 | region &= displayRegion; | ||
136 | } else { | 136 | } else { | ||
137 | // whole screen, not transformed, force region to be full | 137 | // whole screen, not transformed, force region to be full | ||
138 | region = displayRegion; | 138 | region = displayRegion; | ||
139 | } | 139 | } | ||
140 | 140 | | |||
141 | painted_region = region; | 141 | painted_region = region; | ||
142 | repaint_region = repaint; | 142 | repaint_region = repaint; | ||
143 | 143 | | |||
144 | if (*mask & PAINT_SCREEN_BACKGROUND_FIRST) { | | |||
145 | paintBackground(region); | | |||
146 | } | | |||
147 | | ||||
148 | ScreenPaintData data(projection, outputGeometry, screenScale); | 144 | ScreenPaintData data(projection, outputGeometry, screenScale); | ||
zzag: Urgh, this paintBackground() may render something to the back buffer before… | |||||
Tried adding an aboutToStartPainting call here but it errors out constantly. Also expose effects work just fine as is. apol: Tried adding an `aboutToStartPainting` call here but it errors out constantly.
Also expose… | |||||
149 | effects->paintScreen(*mask, region, data); | 145 | effects->paintScreen(*mask, region, data); | ||
150 | 146 | | |||
151 | foreach (Window *w, stacking_order) { | 147 | foreach (Window *w, stacking_order) { | ||
152 | effects->postPaintWindow(effectWindow(w)); | 148 | effects->postPaintWindow(effectWindow(w)); | ||
153 | } | 149 | } | ||
154 | 150 | | |||
155 | effects->postPaintScreen(); | 151 | effects->postPaintScreen(); | ||
156 | 152 | | |||
157 | // make sure not to go outside of the screen area | 153 | // make sure not to go outside of the screen area | ||
158 | *updateRegion = damaged_region; | 154 | *updateRegion = damaged_region; | ||
159 | *validRegion = (region | painted_region) & displayRegion; | 155 | *validRegion = (region | painted_region) & displayRegion; | ||
160 | 156 | | |||
161 | repaint_region = QRegion(); | 157 | repaint_region = QRegion(); | ||
162 | damaged_region = QRegion(); | 158 | damaged_region = QRegion(); | ||
163 | 159 | | |||
160 | m_paintScreenCount = 0; | ||||
161 | | ||||
164 | // make sure all clipping is restored | 162 | // make sure all clipping is restored | ||
165 | Q_ASSERT(!PaintClipper::clip()); | 163 | Q_ASSERT(!PaintClipper::clip()); | ||
166 | } | 164 | } | ||
167 | 165 | | |||
168 | // Compute time since the last painting pass. | 166 | // Compute time since the last painting pass. | ||
169 | void Scene::updateTimeDiff() | 167 | void Scene::updateTimeDiff() | ||
170 | { | 168 | { | ||
171 | if (!last_time.isValid()) { | 169 | if (!last_time.isValid()) { | ||
Show All 16 Lines | |||||
188 | { | 186 | { | ||
189 | // Don't break time since last paint for the next pass. | 187 | // Don't break time since last paint for the next pass. | ||
190 | last_time.invalidate(); | 188 | last_time.invalidate(); | ||
191 | } | 189 | } | ||
192 | 190 | | |||
193 | // the function that'll be eventually called by paintScreen() above | 191 | // the function that'll be eventually called by paintScreen() above | ||
194 | void Scene::finalPaintScreen(int mask, const QRegion ®ion, ScreenPaintData& data) | 192 | void Scene::finalPaintScreen(int mask, const QRegion ®ion, ScreenPaintData& data) | ||
195 | { | 193 | { | ||
194 | m_paintScreenCount++; | ||||
196 | if (mask & (PAINT_SCREEN_TRANSFORMED | PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS)) | 195 | if (mask & (PAINT_SCREEN_TRANSFORMED | PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS)) | ||
197 | paintGenericScreen(mask, data); | 196 | paintGenericScreen(mask, data); | ||
198 | else | 197 | else | ||
199 | paintSimpleScreen(mask, region); | 198 | paintSimpleScreen(mask, region); | ||
200 | } | 199 | } | ||
201 | 200 | | |||
202 | // The generic painting code that can handle even transformations. | 201 | // The generic painting code that can handle even transformations. | ||
203 | // It simply paints bottom-to-top. | 202 | // It simply paints bottom-to-top. | ||
204 | void Scene::paintGenericScreen(int orig_mask, const ScreenPaintData &) | 203 | void Scene::paintGenericScreen(int orig_mask, const ScreenPaintData &) | ||
205 | { | 204 | { | ||
206 | if (!(orig_mask & PAINT_SCREEN_BACKGROUND_FIRST)) { | | |||
207 | paintBackground(infiniteRegion()); | | |||
208 | } | | |||
209 | QVector<Phase2Data> phase2; | 205 | QVector<Phase2Data> phase2; | ||
In general it shouldn't matter, but I wonder whether paintBackground() must be moved down so we don't call glClear() before eglSetDamageRegionKHR(). zzag: In general it shouldn't matter, but I wonder whether paintBackground() must be moved down so we… | |||||
210 | phase2.reserve(stacking_order.size()); | 206 | phase2.reserve(stacking_order.size()); | ||
211 | foreach (Window * w, stacking_order) { // bottom to top | 207 | foreach (Window * w, stacking_order) { // bottom to top | ||
212 | Toplevel* topw = w->window(); | 208 | Toplevel* topw = w->window(); | ||
213 | 209 | | |||
214 | // Reset the repaint_region. | 210 | // Reset the repaint_region. | ||
215 | // This has to be done here because many effects schedule a repaint for | 211 | // This has to be done here because many effects schedule a repaint for | ||
216 | // the next frame within Effects::prePaintWindow. | 212 | // the next frame within Effects::prePaintWindow. | ||
217 | topw->resetRepaints(); | 213 | topw->resetRepaints(); | ||
Show All 12 Lines | 223 | #if !defined(QT_NO_DEBUG) | |||
230 | } | 226 | } | ||
231 | #endif | 227 | #endif | ||
232 | if (!w->isPaintingEnabled()) { | 228 | if (!w->isPaintingEnabled()) { | ||
233 | continue; | 229 | continue; | ||
234 | } | 230 | } | ||
235 | phase2.append({w, infiniteRegion(), data.clip, data.mask, data.quads}); | 231 | phase2.append({w, infiniteRegion(), data.clip, data.mask, data.quads}); | ||
236 | } | 232 | } | ||
237 | 233 | | |||
234 | damaged_region = QRegion(QRect {{}, screens()->size()}); | ||||
235 | if (m_paintScreenCount == 1) { | ||||
So, when the slide effect is active, aboutToStartPainting() may be called up to 4 times. We have to check m_paintScreenCount before calling aboutToStartPainting(). zzag: So, when the slide effect is active, aboutToStartPainting() may be called up to 4 times. We… | |||||
zzag: You must call paintBackground if PAINT_SCREEN_BACKGROUND_FIRST is called. | |||||
zzag: is set* | |||||
apol: This happens in Scene::paintScreen. | |||||
But this means that paintBackground() will be called before abotToStartPainting(). The whole purpose of m_paintScreenCount is to ensure that we can move paintBackgroudn() from Scene::paintScreen() to Scene::paintGenericScreen() and Scene::paintSimpleScreen(). zzag: But this means that paintBackground() will be called before abotToStartPainting(). The whole… | |||||
236 | aboutToStartPainting(damaged_region); | ||||
237 | | ||||
238 | if (orig_mask & PAINT_SCREEN_BACKGROUND_FIRST) { | ||||
239 | paintBackground(infiniteRegion()); | ||||
240 | } | ||||
In general, an effect is allowed to call paintScreen() multiple times without setting PAINT_SCREEN_BACKGROUND_FIRST. zzag: In general, an effect is allowed to call paintScreen() multiple times without setting… | |||||
241 | } | ||||
242 | | ||||
243 | if (!(orig_mask & PAINT_SCREEN_BACKGROUND_FIRST)) { | ||||
244 | paintBackground(infiniteRegion()); | ||||
245 | } | ||||
238 | foreach (const Phase2Data & d, phase2) { | 246 | foreach (const Phase2Data & d, phase2) { | ||
239 | paintWindow(d.window, d.mask, d.region, d.quads); | 247 | paintWindow(d.window, d.mask, d.region, d.quads); | ||
240 | } | 248 | } | ||
241 | | ||||
242 | const QSize &screenSize = screens()->size(); | | |||
243 | damaged_region = QRegion(0, 0, screenSize.width(), screenSize.height()); | | |||
244 | } | 249 | } | ||
245 | 250 | | |||
246 | // The optimized case without any transformations at all. | 251 | // The optimized case without any transformations at all. | ||
247 | // It can paint only the requested region and can use clipping | 252 | // It can paint only the requested region and can use clipping | ||
248 | // to reduce painting and improve performance. | 253 | // to reduce painting and improve performance. | ||
249 | void Scene::paintSimpleScreen(int orig_mask, const QRegion ®ion) | 254 | void Scene::paintSimpleScreen(int orig_mask, const QRegion ®ion) | ||
250 | { | 255 | { | ||
251 | Q_ASSERT((orig_mask & (PAINT_SCREEN_TRANSFORMED | 256 | Q_ASSERT((orig_mask & (PAINT_SCREEN_TRANSFORMED | ||
▲ Show 20 Lines • Show All 93 Lines • ▼ Show 20 Line(s) | 346 | if (!data->clip.isEmpty() && !(data->mask & PAINT_WINDOW_TRANSLUCENT)) { | |||
345 | if (!fullRepaint) { | 350 | if (!fullRepaint) { | ||
346 | upperTranslucentDamage |= data->region - data->clip; | 351 | upperTranslucentDamage |= data->region - data->clip; | ||
347 | } | 352 | } | ||
348 | } else if (!fullRepaint) { | 353 | } else if (!fullRepaint) { | ||
349 | upperTranslucentDamage |= data->region; | 354 | upperTranslucentDamage |= data->region; | ||
350 | } | 355 | } | ||
351 | } | 356 | } | ||
352 | 357 | | |||
353 | QRegion paintedArea; | 358 | QRegion paintedArea; | ||
354 | // Fill any areas of the root window not covered by opaque windows | 359 | // Fill any areas of the root window not covered by opaque windows | ||
360 | if (m_paintScreenCount == 1) { | ||||
361 | aboutToStartPainting(dirtyArea); | ||||
362 | | ||||
363 | if (orig_mask & PAINT_SCREEN_BACKGROUND_FIRST) { | ||||
zzag: aboutToStartPainting() should not be called twice. | |||||
364 | paintBackground(infiniteRegion()); | ||||
365 | } | ||||
366 | } | ||||
355 | if (!(orig_mask & PAINT_SCREEN_BACKGROUND_FIRST)) { | 367 | if (!(orig_mask & PAINT_SCREEN_BACKGROUND_FIRST)) { | ||
356 | paintedArea = dirtyArea - allclips; | 368 | paintedArea = dirtyArea - allclips; | ||
357 | paintBackground(paintedArea); | 369 | paintBackground(paintedArea); | ||
358 | } | 370 | } | ||
359 | 371 | | |||
360 | // Now walk the list bottom to top and draw the windows. | 372 | // Now walk the list bottom to top and draw the windows. | ||
361 | for (int i = 0; i < phase2data.count(); ++i) { | 373 | for (int i = 0; i < phase2data.count(); ++i) { | ||
362 | Phase2Data *data = &phase2data[i]; | 374 | Phase2Data *data = &phase2data[i]; | ||
▲ Show 20 Lines • Show All 231 Lines • ▼ Show 20 Line(s) | 574 | { | |||
594 | } | 606 | } | ||
595 | } | 607 | } | ||
596 | 608 | | |||
597 | void Scene::paintDesktop(int desktop, int mask, const QRegion ®ion, ScreenPaintData &data) | 609 | void Scene::paintDesktop(int desktop, int mask, const QRegion ®ion, ScreenPaintData &data) | ||
598 | { | 610 | { | ||
599 | static_cast<EffectsHandlerImpl*>(effects)->paintDesktop(desktop, mask, region, data); | 611 | static_cast<EffectsHandlerImpl*>(effects)->paintDesktop(desktop, mask, region, data); | ||
600 | } | 612 | } | ||
601 | 613 | | |||
614 | void Scene::aboutToStartPainting(const QRegion &damage) | ||||
615 | { | ||||
616 | Q_UNUSED(damage) | ||||
zzag: Usually we don't put a semicolon after Q_UNUSED. | |||||
617 | } | ||||
618 | | ||||
602 | // the function that'll be eventually called by paintWindow() above | 619 | // the function that'll be eventually called by paintWindow() above | ||
603 | void Scene::finalPaintWindow(EffectWindowImpl* w, int mask, const QRegion ®ion, WindowPaintData& data) | 620 | void Scene::finalPaintWindow(EffectWindowImpl* w, int mask, const QRegion ®ion, WindowPaintData& data) | ||
604 | { | 621 | { | ||
605 | effects->drawWindow(w, mask, region, data); | 622 | effects->drawWindow(w, mask, region, data); | ||
606 | } | 623 | } | ||
607 | 624 | | |||
608 | // will be eventually called from drawWindow() | 625 | // will be eventually called from drawWindow() | ||
609 | void Scene::finalDrawWindow(EffectWindowImpl* w, int mask, const QRegion ®ion, WindowPaintData& data) | 626 | void Scene::finalDrawWindow(EffectWindowImpl* w, int mask, const QRegion ®ion, WindowPaintData& data) | ||
▲ Show 20 Lines • Show All 591 Lines • Show Last 20 Lines |
Urgh, this paintBackground() may render something to the back buffer before eglSetDamageRegionKHR() is called.