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

Side by Side Diff: Source/platform/graphics/Canvas2DLayerBridge.cpp

Issue 1297663002: Eliminate deferral overhead with canvas to canvas draws (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: git cl web Created 5 years, 4 months 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 | Annotate | Revision Log
« no previous file with comments | « Source/platform/graphics/Canvas2DLayerBridge.h ('k') | Source/platform/graphics/ImageBuffer.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 (C) 2012 Google Inc. All rights reserved. 2 * Copyright (C) 2012 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 7 *
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
91 , m_contextProvider(contextProvider) 91 , m_contextProvider(contextProvider)
92 , m_imageBuffer(0) 92 , m_imageBuffer(0)
93 , m_msaaSampleCount(msaaSampleCount) 93 , m_msaaSampleCount(msaaSampleCount)
94 , m_bytesAllocated(0) 94 , m_bytesAllocated(0)
95 , m_haveRecordedDrawCommands(false) 95 , m_haveRecordedDrawCommands(false)
96 , m_framesPending(0) 96 , m_framesPending(0)
97 , m_destructionInProgress(false) 97 , m_destructionInProgress(false)
98 , m_rateLimitingEnabled(false) 98 , m_rateLimitingEnabled(false)
99 , m_filterQuality(kLow_SkFilterQuality) 99 , m_filterQuality(kLow_SkFilterQuality)
100 , m_isHidden(false) 100 , m_isHidden(false)
101 , m_isDeferralEnabled(true)
101 , m_lastImageId(0) 102 , m_lastImageId(0)
102 , m_lastFilter(GL_LINEAR) 103 , m_lastFilter(GL_LINEAR)
103 , m_opacityMode(opacityMode) 104 , m_opacityMode(opacityMode)
104 , m_size(m_surface->width(), m_surface->height()) 105 , m_size(m_surface->width(), m_surface->height())
105 { 106 {
106 ASSERT(m_surface); 107 ASSERT(m_surface);
107 ASSERT(m_contextProvider); 108 ASSERT(m_contextProvider);
108 m_initialSurfaceSaveCount = m_surface->getCanvas()->getSaveCount(); 109 m_initialSurfaceSaveCount = m_surface->getCanvas()->getSaveCount();
109 // Used by browser tests to detect the use of a Canvas2DLayerBridge. 110 // Used by browser tests to detect the use of a Canvas2DLayerBridge.
110 TRACE_EVENT_INSTANT0("test_gpu", "Canvas2DLayerBridgeCreation", TRACE_EVENT_ SCOPE_GLOBAL); 111 TRACE_EVENT_INSTANT0("test_gpu", "Canvas2DLayerBridgeCreation", TRACE_EVENT_ SCOPE_GLOBAL);
(...skipping 14 matching lines...) Expand all
125 ASSERT(m_destructionInProgress); 126 ASSERT(m_destructionInProgress);
126 m_layer.clear(); 127 m_layer.clear();
127 ASSERT(m_mailboxes.size() == 0); 128 ASSERT(m_mailboxes.size() == 0);
128 #ifndef NDEBUG 129 #ifndef NDEBUG
129 canvas2DLayerBridgeInstanceCounter.decrement(); 130 canvas2DLayerBridgeInstanceCounter.decrement();
130 #endif 131 #endif
131 } 132 }
132 133
133 void Canvas2DLayerBridge::startRecording() 134 void Canvas2DLayerBridge::startRecording()
134 { 135 {
136 ASSERT(m_isDeferralEnabled);
135 m_recorder = adoptPtr(new SkPictureRecorder); 137 m_recorder = adoptPtr(new SkPictureRecorder);
136 m_recorder->beginRecording(m_size.width(), m_size.height(), nullptr); 138 m_recorder->beginRecording(m_size.width(), m_size.height(), nullptr);
137 if (m_imageBuffer) { 139 if (m_imageBuffer) {
138 m_imageBuffer->resetCanvas(m_recorder->getRecordingCanvas()); 140 m_imageBuffer->resetCanvas(m_recorder->getRecordingCanvas());
139 } 141 }
140 } 142 }
141 143
142 SkCanvas* Canvas2DLayerBridge::canvas() 144 SkCanvas* Canvas2DLayerBridge::canvas()
143 { 145 {
146 if (!m_isDeferralEnabled)
147 return m_surface->getCanvas();
144 return m_recorder->getRecordingCanvas(); 148 return m_recorder->getRecordingCanvas();
145 } 149 }
146 150
147 SkCanvas* Canvas2DLayerBridge::immediateCanvas() 151 void Canvas2DLayerBridge::disableDeferral()
148 { 152 {
149 if (!m_surface) 153 // Disabling deferral is permanent: once triggered by disableDeferral()
150 return nullptr; 154 // we stay in immediate mode indefinitely. This is a performance heuristic
155 // that significantly helps a number of use cases. The rationale is that if
156 // immediate rendering was needed once, it is likely to be needed at least
157 // once per frame, which eliminates the possibility for inter-frame
158 // overdraw optimization. Furthermore, in cases where immediate mode is
159 // required multiple times per frame, the repeated flushing of deferred
160 // commands would cause significant overhead, so it is better to just stop
161 // trying to defer altogether.
162 if (!m_isDeferralEnabled)
163 return;
164
165 m_isDeferralEnabled = false;
151 flushRecordingOnly(); 166 flushRecordingOnly();
152 167 m_recorder.clear();
153 // install the current matrix/clip stack onto the immediate canvas 168 // install the current matrix/clip stack onto the immediate canvas
154 m_surface->getCanvas()->restoreToCount(m_initialSurfaceSaveCount);
155 m_imageBuffer->resetCanvas(m_surface->getCanvas()); 169 m_imageBuffer->resetCanvas(m_surface->getCanvas());
156
157 return m_surface->getCanvas();
158 } 170 }
159 171
160 void Canvas2DLayerBridge::setImageBuffer(ImageBuffer* imageBuffer) 172 void Canvas2DLayerBridge::setImageBuffer(ImageBuffer* imageBuffer)
161 { 173 {
162 m_imageBuffer = imageBuffer; 174 m_imageBuffer = imageBuffer;
163 if (m_imageBuffer) { 175 if (m_imageBuffer && m_isDeferralEnabled) {
164 m_imageBuffer->resetCanvas(m_recorder->getRecordingCanvas()); 176 m_imageBuffer->resetCanvas(m_recorder->getRecordingCanvas());
165 } 177 }
166 } 178 }
167 179
168 void Canvas2DLayerBridge::beginDestruction() 180 void Canvas2DLayerBridge::beginDestruction()
169 { 181 {
170 ASSERT(!m_destructionInProgress); 182 ASSERT(!m_destructionInProgress);
171 setRateLimitingEnabled(false); 183 setRateLimitingEnabled(false);
172 m_recorder.clear(); 184 m_recorder.clear();
173 m_imageBuffer = nullptr; 185 m_imageBuffer = nullptr;
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 m_layer->setRateLimitContext(m_rateLimitingEnabled); 251 m_layer->setRateLimitContext(m_rateLimitingEnabled);
240 } 252 }
241 } 253 }
242 254
243 void Canvas2DLayerBridge::flushRecordingOnly() 255 void Canvas2DLayerBridge::flushRecordingOnly()
244 { 256 {
245 ASSERT(!m_destructionInProgress); 257 ASSERT(!m_destructionInProgress);
246 if (m_haveRecordedDrawCommands && m_surface) { 258 if (m_haveRecordedDrawCommands && m_surface) {
247 TRACE_EVENT0("cc", "Canvas2DLayerBridge::flush"); 259 TRACE_EVENT0("cc", "Canvas2DLayerBridge::flush");
248 RefPtr<SkPicture> picture = adoptRef(m_recorder->endRecording()); 260 RefPtr<SkPicture> picture = adoptRef(m_recorder->endRecording());
249 m_surface->getCanvas()->restoreToCount(m_initialSurfaceSaveCount); // In case immediateCanvas() was used
250 picture->playback(m_surface->getCanvas()); 261 picture->playback(m_surface->getCanvas());
251 startRecording(); 262 if (m_isDeferralEnabled)
263 startRecording();
252 m_haveRecordedDrawCommands = false; 264 m_haveRecordedDrawCommands = false;
253 } 265 }
254 } 266 }
255 267
256 void Canvas2DLayerBridge::flush() 268 void Canvas2DLayerBridge::flush()
257 { 269 {
258 if (!m_surface) 270 if (!m_surface)
259 return; 271 return;
260 flushRecordingOnly(); 272 flushRecordingOnly();
261 m_surface->getCanvas()->flush(); 273 m_surface->getCanvas()->flush();
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
472 484
473 WebLayer* Canvas2DLayerBridge::layer() const 485 WebLayer* Canvas2DLayerBridge::layer() const
474 { 486 {
475 ASSERT(!m_destructionInProgress); 487 ASSERT(!m_destructionInProgress);
476 ASSERT(m_layer); 488 ASSERT(m_layer);
477 return m_layer->layer(); 489 return m_layer->layer();
478 } 490 }
479 491
480 void Canvas2DLayerBridge::didDraw() 492 void Canvas2DLayerBridge::didDraw()
481 { 493 {
482 m_haveRecordedDrawCommands = true; 494 if (m_isDeferralEnabled)
495 m_haveRecordedDrawCommands = true;
483 } 496 }
484 497
485 void Canvas2DLayerBridge::finalizeFrame(const FloatRect &dirtyRect) 498 void Canvas2DLayerBridge::finalizeFrame(const FloatRect &dirtyRect)
486 { 499 {
487 ASSERT(!m_destructionInProgress); 500 ASSERT(!m_destructionInProgress);
488 m_layer->layer()->invalidateRect(enclosingIntRect(dirtyRect)); 501 m_layer->layer()->invalidateRect(enclosingIntRect(dirtyRect));
489
490 m_framesPending++; 502 m_framesPending++;
491 if (m_framesPending > 1) { 503 if (m_framesPending > 1) {
492 // Turn on the rate limiter if this layer tends to accumulate a 504 // Turn on the rate limiter if this layer tends to accumulate a
493 // non-discardable multi-frame backlog of draw commands. 505 // non-discardable multi-frame backlog of draw commands.
494 setRateLimitingEnabled(true); 506 setRateLimitingEnabled(true);
495 } 507 }
496 if (m_rateLimitingEnabled) { 508 if (m_rateLimitingEnabled) {
497 flush(); 509 flush();
498 } 510 }
499 } 511 }
(...skipping 16 matching lines...) Expand all
516 skipQueuedDrawCommands(); 528 skipQueuedDrawCommands();
517 } 529 }
518 530
519 Canvas2DLayerBridge::MailboxInfo::MailboxInfo(const MailboxInfo& other) { 531 Canvas2DLayerBridge::MailboxInfo::MailboxInfo(const MailboxInfo& other) {
520 memcpy(&m_mailbox, &other.m_mailbox, sizeof(m_mailbox)); 532 memcpy(&m_mailbox, &other.m_mailbox, sizeof(m_mailbox));
521 m_image = other.m_image; 533 m_image = other.m_image;
522 m_parentLayerBridge = other.m_parentLayerBridge; 534 m_parentLayerBridge = other.m_parentLayerBridge;
523 } 535 }
524 536
525 } // namespace blink 537 } // namespace blink
OLDNEW
« no previous file with comments | « Source/platform/graphics/Canvas2DLayerBridge.h ('k') | Source/platform/graphics/ImageBuffer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698