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

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

Issue 22929012: Change Canvas2DLayerBridge to stay alive until last mailbox is returned. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: gcc build fix Created 7 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
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 26 matching lines...) Expand all
37 #include "core/platform/graphics/gpu/SharedGraphicsContext3D.h" 37 #include "core/platform/graphics/gpu/SharedGraphicsContext3D.h"
38 #include "public/platform/Platform.h" 38 #include "public/platform/Platform.h"
39 #include "public/platform/WebCompositorSupport.h" 39 #include "public/platform/WebCompositorSupport.h"
40 #include "public/platform/WebGraphicsContext3D.h" 40 #include "public/platform/WebGraphicsContext3D.h"
41 41
42 using WebKit::WebExternalTextureLayer; 42 using WebKit::WebExternalTextureLayer;
43 using WebKit::WebGraphicsContext3D; 43 using WebKit::WebGraphicsContext3D;
44 44
45 namespace WebCore { 45 namespace WebCore {
46 46
47 void Canvas2DLayerBridgePtr::clear()
48 {
49 if (m_ptr) {
50 m_ptr->destroy();
51 m_ptr.clear();
Stephen White 2013/08/23 14:45:28 MicroNit: This is probably redundant, since we'll
52 }
53 }
54
55 Canvas2DLayerBridgePtr::Canvas2DLayerBridgePtr(const Canvas2DLayerBridgePtr& oth er)
56 {
57 *this = other;
58 }
59
60 Canvas2DLayerBridgePtr& Canvas2DLayerBridgePtr::operator=(const Canvas2DLayerBri dgePtr& other)
61 {
62 m_ptr = other.m_ptr;
63 const_cast<Canvas2DLayerBridgePtr*>(&other)->m_ptr.clear(); // transfer of o wnership
Stephen White 2013/08/23 14:45:28 Hmm. I wonder if you could have a private const cl
64 return *this;
65 }
66
47 static SkSurface* createSurface(GraphicsContext3D* context3D, const IntSize& siz e) 67 static SkSurface* createSurface(GraphicsContext3D* context3D, const IntSize& siz e)
48 { 68 {
49 ASSERT(!context3D->webContext()->isContextLost()); 69 ASSERT(!context3D->webContext()->isContextLost());
50 GrContext* gr = context3D->grContext(); 70 GrContext* gr = context3D->grContext();
51 if (!gr) 71 if (!gr)
52 return 0; 72 return 0;
53 gr->resetContext(); 73 gr->resetContext();
54 SkImage::Info info; 74 SkImage::Info info;
55 info.fWidth = size.width(); 75 info.fWidth = size.width();
56 info.fHeight = size.height(); 76 info.fHeight = size.height();
57 info.fColorType = SkImage::kPMColor_ColorType; 77 info.fColorType = SkImage::kPMColor_ColorType;
58 info.fAlphaType = SkImage::kPremul_AlphaType; 78 info.fAlphaType = SkImage::kPremul_AlphaType;
59 return SkSurface::NewRenderTarget(gr, info); 79 return SkSurface::NewRenderTarget(gr, info);
60 } 80 }
61 81
62 PassOwnPtr<Canvas2DLayerBridge> Canvas2DLayerBridge::create(PassRefPtr<GraphicsC ontext3D> context, const IntSize& size, OpacityMode opacityMode) 82 Canvas2DLayerBridgePtr Canvas2DLayerBridge::create(PassRefPtr<GraphicsContext3D> context, const IntSize& size, OpacityMode opacityMode)
63 { 83 {
64 TRACE_EVENT_INSTANT0("test_gpu", "Canvas2DLayerBridgeCreation"); 84 TRACE_EVENT_INSTANT0("test_gpu", "Canvas2DLayerBridgeCreation");
65 SkAutoTUnref<SkSurface> surface(createSurface(context.get(), size)); 85 SkAutoTUnref<SkSurface> surface(createSurface(context.get(), size));
66 if (!surface.get()) 86 if (!surface.get()) {
67 return PassOwnPtr<Canvas2DLayerBridge>(); 87 Canvas2DLayerBridgePtr result;
88 return result;
89 }
68 SkDeferredCanvas* canvas = SkDeferredCanvas::Create(surface.get()); 90 SkDeferredCanvas* canvas = SkDeferredCanvas::Create(surface.get());
69 OwnPtr<Canvas2DLayerBridge> layerBridge = adoptPtr(new Canvas2DLayerBridge(c ontext, canvas, opacityMode)); 91 RefPtr<Canvas2DLayerBridge> layerBridge = adoptRef(new Canvas2DLayerBridge(c ontext, canvas, opacityMode));
70 return layerBridge.release(); 92 Canvas2DLayerBridgePtr result(layerBridge.release());
93 return result;
71 } 94 }
72 95
73 Canvas2DLayerBridge::Canvas2DLayerBridge(PassRefPtr<GraphicsContext3D> context, SkDeferredCanvas* canvas, OpacityMode opacityMode) 96 Canvas2DLayerBridge::Canvas2DLayerBridge(PassRefPtr<GraphicsContext3D> context, SkDeferredCanvas* canvas, OpacityMode opacityMode)
74 : m_canvas(canvas) 97 : m_canvas(canvas)
75 , m_context(context) 98 , m_context(context)
76 , m_bytesAllocated(0) 99 , m_bytesAllocated(0)
77 , m_didRecordDrawCommand(false) 100 , m_didRecordDrawCommand(false)
78 , m_surfaceIsValid(true) 101 , m_surfaceIsValid(true)
79 , m_framesPending(0) 102 , m_framesPending(0)
103 , m_liveMailboxCount(0)
104 , m_destructionInProgress(false)
80 , m_rateLimitingEnabled(false) 105 , m_rateLimitingEnabled(false)
81 , m_next(0) 106 , m_next(0)
82 , m_prev(0) 107 , m_prev(0)
83 , m_lastImageId(0) 108 , m_lastImageId(0)
84 { 109 {
85 ASSERT(m_canvas); 110 ASSERT(m_canvas);
86 // Used by browser tests to detect the use of a Canvas2DLayerBridge. 111 // Used by browser tests to detect the use of a Canvas2DLayerBridge.
87 TRACE_EVENT_INSTANT0("test_gpu", "Canvas2DLayerBridgeCreation"); 112 TRACE_EVENT_INSTANT0("test_gpu", "Canvas2DLayerBridgeCreation");
88 m_layer = adoptPtr(WebKit::Platform::current()->compositorSupport()->createE xternalTextureLayer(this)); 113 m_layer = adoptPtr(WebKit::Platform::current()->compositorSupport()->createE xternalTextureLayer(this));
89 m_layer->setOpaque(opacityMode == Opaque); 114 m_layer->setOpaque(opacityMode == Opaque);
90 m_layer->setBlendBackgroundColor(opacityMode != Opaque); 115 m_layer->setBlendBackgroundColor(opacityMode != Opaque);
91 GraphicsLayer::registerContentsLayer(m_layer->layer()); 116 GraphicsLayer::registerContentsLayer(m_layer->layer());
92 m_layer->setRateLimitContext(m_rateLimitingEnabled); 117 m_layer->setRateLimitContext(m_rateLimitingEnabled);
93 m_canvas->setNotificationClient(this); 118 m_canvas->setNotificationClient(this);
94 } 119 }
95 120
96 Canvas2DLayerBridge::~Canvas2DLayerBridge() 121 Canvas2DLayerBridge::~Canvas2DLayerBridge()
97 { 122 {
123 ASSERT(m_destructionInProgress);
124 m_layer.clear();
125 Vector<MailboxInfo>::iterator mailboxInfo;
126 for (mailboxInfo = m_mailboxes.begin(); mailboxInfo < m_mailboxes.end(); mai lboxInfo++) {
127 ASSERT(mailboxInfo->m_status != MailboxInUse);
128 if (mailboxInfo->m_status == MailboxReleased) {
129 if (mailboxInfo->m_mailbox.syncPoint) {
130 context()->waitSyncPoint(mailboxInfo->m_mailbox.syncPoint);
131 mailboxInfo->m_mailbox.syncPoint = 0;
132 }
133 // Invalidate texture state in case the compositor altered it since the copy-on-write.
134 mailboxInfo->m_image->getTexture()->invalidateCachedState();
135 }
136 }
137 m_mailboxes.clear();
138 }
139
140 void Canvas2DLayerBridge::destroy()
141 {
142 ASSERT(!m_destructionInProgress);
143 m_destructionInProgress = true;
98 GraphicsLayer::unregisterContentsLayer(m_layer->layer()); 144 GraphicsLayer::unregisterContentsLayer(m_layer->layer());
145 m_canvas->setNotificationClient(0);
146 m_layer->clearTexture();
99 Canvas2DLayerManager::get().layerToBeDestroyed(this); 147 Canvas2DLayerManager::get().layerToBeDestroyed(this);
100 m_canvas->setNotificationClient(0);
101 m_mailboxes.clear();
102 m_layer->clearTexture();
103 m_layer.clear();
104 } 148 }
105 149
106 void Canvas2DLayerBridge::limitPendingFrames() 150 void Canvas2DLayerBridge::limitPendingFrames()
107 { 151 {
152 ASSERT(!m_destructionInProgress);
108 if (m_didRecordDrawCommand) { 153 if (m_didRecordDrawCommand) {
109 m_framesPending++; 154 m_framesPending++;
110 m_didRecordDrawCommand = false; 155 m_didRecordDrawCommand = false;
111 if (m_framesPending > 1) { 156 if (m_framesPending > 1) {
112 // Turn on the rate limiter if this layer tends to accumulate a 157 // Turn on the rate limiter if this layer tends to accumulate a
113 // non-discardable multi-frame backlog of draw commands. 158 // non-discardable multi-frame backlog of draw commands.
114 setRateLimitingEnabled(true); 159 setRateLimitingEnabled(true);
115 } 160 }
116 if (m_rateLimitingEnabled) { 161 if (m_rateLimitingEnabled) {
117 flush(); 162 flush();
118 } 163 }
119 } 164 }
120 } 165 }
121 166
122 void Canvas2DLayerBridge::prepareForDraw() 167 void Canvas2DLayerBridge::prepareForDraw()
123 { 168 {
169 ASSERT(!m_destructionInProgress);
124 ASSERT(m_layer); 170 ASSERT(m_layer);
125 if (!isValid()) { 171 if (!isValid()) {
126 if (m_canvas) { 172 if (m_canvas) {
127 // drop pending commands because there is no surface to draw to 173 // drop pending commands because there is no surface to draw to
128 m_canvas->silentFlush(); 174 m_canvas->silentFlush();
129 } 175 }
130 return; 176 return;
131 } 177 }
132 m_context->makeContextCurrent(); 178 m_context->makeContextCurrent();
133 } 179 }
134 180
135 void Canvas2DLayerBridge::storageAllocatedForRecordingChanged(size_t bytesAlloca ted) 181 void Canvas2DLayerBridge::storageAllocatedForRecordingChanged(size_t bytesAlloca ted)
136 { 182 {
183 ASSERT(!m_destructionInProgress);
137 intptr_t delta = (intptr_t)bytesAllocated - (intptr_t)m_bytesAllocated; 184 intptr_t delta = (intptr_t)bytesAllocated - (intptr_t)m_bytesAllocated;
138 m_bytesAllocated = bytesAllocated; 185 m_bytesAllocated = bytesAllocated;
139 Canvas2DLayerManager::get().layerAllocatedStorageChanged(this, delta); 186 Canvas2DLayerManager::get().layerAllocatedStorageChanged(this, delta);
140 } 187 }
141 188
142 size_t Canvas2DLayerBridge::storageAllocatedForRecording() 189 size_t Canvas2DLayerBridge::storageAllocatedForRecording()
143 { 190 {
191 ASSERT(!m_destructionInProgress);
144 return m_canvas->storageAllocatedForRecording(); 192 return m_canvas->storageAllocatedForRecording();
145 } 193 }
146 194
147 void Canvas2DLayerBridge::flushedDrawCommands() 195 void Canvas2DLayerBridge::flushedDrawCommands()
148 { 196 {
197 ASSERT(!m_destructionInProgress);
149 storageAllocatedForRecordingChanged(storageAllocatedForRecording()); 198 storageAllocatedForRecordingChanged(storageAllocatedForRecording());
150 m_framesPending = 0; 199 m_framesPending = 0;
151 } 200 }
152 201
153 void Canvas2DLayerBridge::skippedPendingDrawCommands() 202 void Canvas2DLayerBridge::skippedPendingDrawCommands()
154 { 203 {
204 ASSERT(!m_destructionInProgress);
155 // Stop triggering the rate limiter if SkDeferredCanvas is detecting 205 // Stop triggering the rate limiter if SkDeferredCanvas is detecting
156 // and optimizing overdraw. 206 // and optimizing overdraw.
157 setRateLimitingEnabled(false); 207 setRateLimitingEnabled(false);
158 flushedDrawCommands(); 208 flushedDrawCommands();
159 } 209 }
160 210
161 void Canvas2DLayerBridge::setRateLimitingEnabled(bool enabled) 211 void Canvas2DLayerBridge::setRateLimitingEnabled(bool enabled)
162 { 212 {
213 ASSERT(!m_destructionInProgress || !enabled);
163 if (m_rateLimitingEnabled != enabled) { 214 if (m_rateLimitingEnabled != enabled) {
164 m_rateLimitingEnabled = enabled; 215 m_rateLimitingEnabled = enabled;
165 m_layer->setRateLimitContext(m_rateLimitingEnabled); 216 m_layer->setRateLimitContext(m_rateLimitingEnabled);
166 } 217 }
167 } 218 }
168 219
169 size_t Canvas2DLayerBridge::freeMemoryIfPossible(size_t bytesToFree) 220 size_t Canvas2DLayerBridge::freeMemoryIfPossible(size_t bytesToFree)
170 { 221 {
222 ASSERT(!m_destructionInProgress);
171 size_t bytesFreed = m_canvas->freeMemoryIfPossible(bytesToFree); 223 size_t bytesFreed = m_canvas->freeMemoryIfPossible(bytesToFree);
172 if (bytesFreed) 224 if (bytesFreed)
173 Canvas2DLayerManager::get().layerAllocatedStorageChanged(this, -((intptr _t)bytesFreed)); 225 Canvas2DLayerManager::get().layerAllocatedStorageChanged(this, -((intptr _t)bytesFreed));
174 m_bytesAllocated -= bytesFreed; 226 m_bytesAllocated -= bytesFreed;
175 return bytesFreed; 227 return bytesFreed;
176 } 228 }
177 229
178 void Canvas2DLayerBridge::flush() 230 void Canvas2DLayerBridge::flush()
179 { 231 {
232 ASSERT(!m_destructionInProgress);
180 if (m_canvas->hasPendingCommands()) { 233 if (m_canvas->hasPendingCommands()) {
181 TRACE_EVENT0("cc", "Canvas2DLayerBridge::flush"); 234 TRACE_EVENT0("cc", "Canvas2DLayerBridge::flush");
182 m_canvas->flush(); 235 m_canvas->flush();
183 } 236 }
184 } 237 }
185 238
186 WebGraphicsContext3D* Canvas2DLayerBridge::context() 239 WebGraphicsContext3D* Canvas2DLayerBridge::context()
187 { 240 {
188 // Check on m_layer is necessary because context() may be called during 241 // Check on m_layer is necessary because context() may be called during
189 // the destruction of m_layer 242 // the destruction of m_layer
190 if (m_layer) { 243 if (m_layer) {
191 isValid(); // To ensure rate limiter is disabled if context is lost. 244 isValid(); // To ensure rate limiter is disabled if context is lost.
192 } 245 }
193 return m_context->webContext(); 246 return m_context->webContext();
194 } 247 }
195 248
196 bool Canvas2DLayerBridge::isValid() 249 bool Canvas2DLayerBridge::isValid()
197 { 250 {
198 ASSERT(m_layer); 251 ASSERT(m_layer);
252 if (m_destructionInProgress)
253 return false;
199 if (m_context->webContext()->isContextLost() || !m_surfaceIsValid) { 254 if (m_context->webContext()->isContextLost() || !m_surfaceIsValid) {
200 // Attempt to recover. 255 // Attempt to recover.
201 m_layer->clearTexture(); 256 m_layer->clearTexture();
202 m_mailboxes.clear(); 257 m_mailboxes.clear();
203 RefPtr<GraphicsContext3D> sharedContext = SharedGraphicsContext3D::get() ; 258 RefPtr<GraphicsContext3D> sharedContext = SharedGraphicsContext3D::get() ;
204 if (!sharedContext || sharedContext->webContext()->isContextLost()) { 259 if (!sharedContext || sharedContext->webContext()->isContextLost()) {
205 m_surfaceIsValid = false; 260 m_surfaceIsValid = false;
206 } else { 261 } else {
207 m_context = sharedContext; 262 m_context = sharedContext;
208 IntSize size(m_canvas->getTopDevice()->width(), m_canvas->getTopDevi ce()->height()); 263 IntSize size(m_canvas->getTopDevice()->width(), m_canvas->getTopDevi ce()->height());
209 SkAutoTUnref<SkSurface> surface(createSurface(m_context.get(), size) ); 264 SkAutoTUnref<SkSurface> surface(createSurface(m_context.get(), size) );
210 if (surface.get()) { 265 if (surface.get()) {
211 m_canvas->setSurface(surface.get()); 266 m_canvas->setSurface(surface.get());
212 m_surfaceIsValid = true; 267 m_surfaceIsValid = true;
213 // FIXME: draw sad canvas picture into new buffer crbug.com/2438 42 268 // FIXME: draw sad canvas picture into new buffer crbug.com/2438 42
214 } else { 269 } else {
215 // Surface allocation failed. Set m_surfaceIsValid to false to 270 // Surface allocation failed. Set m_surfaceIsValid to false to
216 // trigger subsequent retry. 271 // trigger subsequent retry.
217 m_surfaceIsValid = false; 272 m_surfaceIsValid = false;
218 } 273 }
219 } 274 }
220 } 275 }
221 if (!m_surfaceIsValid) 276 if (!m_surfaceIsValid)
222 setRateLimitingEnabled(false); 277 setRateLimitingEnabled(false);
223 return m_surfaceIsValid; 278 return m_surfaceIsValid;
224
225 } 279 }
226 280
227 bool Canvas2DLayerBridge::prepareMailbox(WebKit::WebExternalTextureMailbox* outM ailbox, WebKit::WebExternalBitmap* bitmap) 281 bool Canvas2DLayerBridge::prepareMailbox(WebKit::WebExternalTextureMailbox* outM ailbox, WebKit::WebExternalBitmap* bitmap)
228 { 282 {
283 if (m_destructionInProgress) {
284 const WebKit::WebExternalTextureMailbox emptyMailbox;
285 *outMailbox = emptyMailbox;
286 return true;
287 }
229 ASSERT(!bitmap); 288 ASSERT(!bitmap);
230 if (!isValid()) 289 if (!isValid())
231 return false; 290 return false;
232 // Release to skia textures that were previouosly released by the 291 // Release to skia textures that were previouosly released by the
233 // compositor. We do this before acquiring the next snapshot in 292 // compositor. We do this before acquiring the next snapshot in
234 // order to cap maximum gpu memory consumption. 293 // order to cap maximum gpu memory consumption.
235 m_context->makeContextCurrent(); 294 m_context->makeContextCurrent();
236 flush(); 295 flush();
237 Vector<MailboxInfo>::iterator mailboxInfo; 296 Vector<MailboxInfo>::iterator mailboxInfo;
238 for (mailboxInfo = m_mailboxes.begin(); mailboxInfo < m_mailboxes.end(); mai lboxInfo++) { 297 for (mailboxInfo = m_mailboxes.begin(); mailboxInfo < m_mailboxes.end(); mai lboxInfo++) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
271 m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::T EXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE); 330 m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::T EXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE);
272 m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::T EXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE); 331 m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::T EXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE);
273 context()->produceTextureCHROMIUM(GraphicsContext3D::TEXTURE_2D, mailboxInfo ->m_mailbox.name); 332 context()->produceTextureCHROMIUM(GraphicsContext3D::TEXTURE_2D, mailboxInfo ->m_mailbox.name);
274 context()->flush(); 333 context()->flush();
275 mailboxInfo->m_mailbox.syncPoint = context()->insertSyncPoint(); 334 mailboxInfo->m_mailbox.syncPoint = context()->insertSyncPoint();
276 m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, 0); 335 m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, 0);
277 // Because we are changing the texture binding without going through skia, 336 // Because we are changing the texture binding without going through skia,
278 // we must dirty the context. 337 // we must dirty the context.
279 m_context->grContext()->resetContext(kTextureBinding_GrGLBackendState); 338 m_context->grContext()->resetContext(kTextureBinding_GrGLBackendState);
280 339
340 // set m_parentLayerBridge to make sure 'this' stays alive as long as it has
341 // live mailboxes
342 ASSERT(!mailboxInfo->m_parentLayerBridge);
343 this->ref(); // Because we are adopting an already referenced object
344 mailboxInfo->m_parentLayerBridge = adoptRef(this);
345 m_liveMailboxCount++;
Stephen White 2013/08/23 14:45:28 m_liveMailboxCount seems to be only written now, a
281 *outMailbox = mailboxInfo->m_mailbox; 346 *outMailbox = mailboxInfo->m_mailbox;
282 return true; 347 return true;
283 } 348 }
284 349
285 Canvas2DLayerBridge::MailboxInfo* Canvas2DLayerBridge::createMailboxInfo() { 350 Canvas2DLayerBridge::MailboxInfo* Canvas2DLayerBridge::createMailboxInfo() {
351 ASSERT(!m_destructionInProgress);
286 MailboxInfo* mailboxInfo; 352 MailboxInfo* mailboxInfo;
287 for (mailboxInfo = m_mailboxes.begin(); mailboxInfo < m_mailboxes.end(); mai lboxInfo++) { 353 for (mailboxInfo = m_mailboxes.begin(); mailboxInfo < m_mailboxes.end(); mai lboxInfo++) {
288 if (mailboxInfo->m_status == MailboxAvailable) { 354 if (mailboxInfo->m_status == MailboxAvailable) {
289 return mailboxInfo; 355 return mailboxInfo;
290 } 356 }
291 } 357 }
292 358
293 // No available mailbox: create one. 359 // No available mailbox: create one.
294 m_mailboxes.grow(m_mailboxes.size() + 1); 360 m_mailboxes.grow(m_mailboxes.size() + 1);
295 mailboxInfo = &m_mailboxes.last(); 361 mailboxInfo = &m_mailboxes.last();
(...skipping 10 matching lines...) Expand all
306 } 372 }
307 373
308 void Canvas2DLayerBridge::mailboxReleased(const WebKit::WebExternalTextureMailbo x& mailbox) 374 void Canvas2DLayerBridge::mailboxReleased(const WebKit::WebExternalTextureMailbo x& mailbox)
309 { 375 {
310 Vector<MailboxInfo>::iterator mailboxInfo; 376 Vector<MailboxInfo>::iterator mailboxInfo;
311 for (mailboxInfo = m_mailboxes.begin(); mailboxInfo < m_mailboxes.end(); mai lboxInfo++) { 377 for (mailboxInfo = m_mailboxes.begin(); mailboxInfo < m_mailboxes.end(); mai lboxInfo++) {
312 if (!memcmp(mailboxInfo->m_mailbox.name, mailbox.name, sizeof(mailbox.na me))) { 378 if (!memcmp(mailboxInfo->m_mailbox.name, mailbox.name, sizeof(mailbox.na me))) {
313 mailboxInfo->m_mailbox.syncPoint = mailbox.syncPoint; 379 mailboxInfo->m_mailbox.syncPoint = mailbox.syncPoint;
314 ASSERT(mailboxInfo->m_status == MailboxInUse); 380 ASSERT(mailboxInfo->m_status == MailboxInUse);
315 mailboxInfo->m_status = MailboxReleased; 381 mailboxInfo->m_status = MailboxReleased;
382 // Trigger Canvas2DLayerBridge self-destruction if this is the
383 // last live mailbox and the layer bridge is not externally
384 // referenced.
385 ASSERT(mailboxInfo->m_parentLayerBridge.get() == this);
386 m_liveMailboxCount--;
387 mailboxInfo->m_parentLayerBridge.clear();
316 return; 388 return;
317 } 389 }
318 } 390 }
319 } 391 }
320 392
321 WebKit::WebLayer* Canvas2DLayerBridge::layer() 393 WebKit::WebLayer* Canvas2DLayerBridge::layer()
322 { 394 {
323 ASSERT(m_layer); 395 ASSERT(m_layer);
324 return m_layer->layer(); 396 return m_layer->layer();
325 } 397 }
326 398
327 void Canvas2DLayerBridge::contextAcquired() 399 void Canvas2DLayerBridge::contextAcquired()
328 { 400 {
401 ASSERT(!m_destructionInProgress);
329 Canvas2DLayerManager::get().layerDidDraw(this); 402 Canvas2DLayerManager::get().layerDidDraw(this);
330 m_didRecordDrawCommand = true; 403 m_didRecordDrawCommand = true;
331 } 404 }
332 405
333 unsigned Canvas2DLayerBridge::backBufferTexture() 406 unsigned Canvas2DLayerBridge::backBufferTexture()
334 { 407 {
408 ASSERT(!m_destructionInProgress);
335 if (!isValid()) 409 if (!isValid())
336 return 0; 410 return 0;
337 contextAcquired(); 411 contextAcquired();
338 m_canvas->flush(); 412 m_canvas->flush();
339 m_context->flush(); 413 m_context->flush();
340 GrRenderTarget* renderTarget = reinterpret_cast<GrRenderTarget*>(m_canvas->g etDevice()->accessRenderTarget()); 414 GrRenderTarget* renderTarget = reinterpret_cast<GrRenderTarget*>(m_canvas->g etDevice()->accessRenderTarget());
341 if (renderTarget) { 415 if (renderTarget) {
342 return renderTarget->asTexture()->getTextureHandle(); 416 return renderTarget->asTexture()->getTextureHandle();
343 } 417 }
344 return 0; 418 return 0;
345 } 419 }
346 420
347 Canvas2DLayerBridge::MailboxInfo::MailboxInfo(const MailboxInfo& other) { 421 Canvas2DLayerBridge::MailboxInfo::MailboxInfo(const MailboxInfo& other) {
348 // This copy constructor should only be used for Vector reallocation 422 // This copy constructor should only be used for Vector reallocation
349 // Assuming 'other' is to be destroyed, we swap m_image ownership 423 // Assuming 'other' is to be destroyed, we swap m_image ownership
350 // rather than do a refcount dance. 424 // rather than do a refcount dance.
351 memcpy(&m_mailbox, &other.m_mailbox, sizeof(m_mailbox)); 425 memcpy(&m_mailbox, &other.m_mailbox, sizeof(m_mailbox));
352 m_image.swap(const_cast<SkAutoTUnref<SkImage>*>(&other.m_image)); 426 m_image.swap(const_cast<SkAutoTUnref<SkImage>*>(&other.m_image));
353 m_status = other.m_status; 427 m_status = other.m_status;
354 } 428 }
355 429
356 } 430 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698