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

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

Issue 186023003: Speculative fix for crash in Canvas2DLayerBridge::freeReleasedMailbox (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: built a shed for my bike Created 6 years, 9 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') | no next file » | 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 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
197 } 197 }
198 ++m_framesSinceMailboxRelease; 198 ++m_framesSinceMailboxRelease;
199 if (releasedMailboxHasExpired()) { 199 if (releasedMailboxHasExpired()) {
200 freeReleasedMailbox(); 200 freeReleasedMailbox();
201 } 201 }
202 } 202 }
203 203
204 void Canvas2DLayerBridge::prepareForDraw() 204 void Canvas2DLayerBridge::prepareForDraw()
205 { 205 {
206 ASSERT(m_layer); 206 ASSERT(m_layer);
207 if (!isValid()) { 207 if (!surfaceIsValid() && !recoverSurface()) {
208 if (m_canvas) { 208 if (m_canvas) {
209 // drop pending commands because there is no surface to draw to 209 // drop pending commands because there is no surface to draw to
210 m_canvas->silentFlush(); 210 m_canvas->silentFlush();
211 } 211 }
212 return; 212 return;
213 } 213 }
214 context()->makeContextCurrent(); 214 context()->makeContextCurrent();
215 } 215 }
216 216
217 void Canvas2DLayerBridge::storageAllocatedForRecordingChanged(size_t bytesAlloca ted) 217 void Canvas2DLayerBridge::storageAllocatedForRecordingChanged(size_t bytesAlloca ted)
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
280 return hasReleasedMailbox() ? &m_mailboxes[m_releasedMailboxInfoIndex] : 0; 280 return hasReleasedMailbox() ? &m_mailboxes[m_releasedMailboxInfoIndex] : 0;
281 } 281 }
282 282
283 bool Canvas2DLayerBridge::hasReleasedMailbox() const 283 bool Canvas2DLayerBridge::hasReleasedMailbox() const
284 { 284 {
285 return m_releasedMailboxInfoIndex != InvalidMailboxIndex; 285 return m_releasedMailboxInfoIndex != InvalidMailboxIndex;
286 } 286 }
287 287
288 void Canvas2DLayerBridge::freeReleasedMailbox() 288 void Canvas2DLayerBridge::freeReleasedMailbox()
289 { 289 {
290 if (m_contextProvider->context3d()->isContextLost() || !m_surfaceIsValid)
291 return;
290 MailboxInfo* mailboxInfo = releasedMailboxInfo(); 292 MailboxInfo* mailboxInfo = releasedMailboxInfo();
291 if (!mailboxInfo) 293 if (!mailboxInfo)
292 return; 294 return;
293 295
294 ASSERT(mailboxInfo->m_status == MailboxReleased); 296 ASSERT(mailboxInfo->m_status == MailboxReleased);
295 if (mailboxInfo->m_mailbox.syncPoint) { 297 if (mailboxInfo->m_mailbox.syncPoint) {
296 context()->waitSyncPoint(mailboxInfo->m_mailbox.syncPoint); 298 context()->waitSyncPoint(mailboxInfo->m_mailbox.syncPoint);
297 mailboxInfo->m_mailbox.syncPoint = 0; 299 mailboxInfo->m_mailbox.syncPoint = 0;
298 } 300 }
299 // Invalidate texture state in case the compositor altered it since the copy -on-write. 301 // Invalidate texture state in case the compositor altered it since the copy -on-write.
300 if (mailboxInfo->m_image) { 302 if (mailboxInfo->m_image) {
301 if (isHidden() || releasedMailboxHasExpired()) 303 if (isHidden() || releasedMailboxHasExpired())
302 mailboxInfo->m_image->getTexture()->resetFlag(static_cast<GrTextureF lags>(GrTexture::kReturnToCache_FlagBit)); 304 mailboxInfo->m_image->getTexture()->resetFlag(static_cast<GrTextureF lags>(GrTexture::kReturnToCache_FlagBit));
303 mailboxInfo->m_image->getTexture()->invalidateCachedState(); 305 mailboxInfo->m_image->getTexture()->invalidateCachedState();
304 mailboxInfo->m_image.clear(); 306 mailboxInfo->m_image.clear();
305 } 307 }
306 mailboxInfo->m_status = MailboxAvailable; 308 mailboxInfo->m_status = MailboxAvailable;
307 m_releasedMailboxInfoIndex = InvalidMailboxIndex; 309 m_releasedMailboxInfoIndex = InvalidMailboxIndex;
308 Canvas2DLayerManager::get().layerTransientResourceAllocationChanged(this); 310 Canvas2DLayerManager::get().layerTransientResourceAllocationChanged(this);
309 } 311 }
310 312
311 blink::WebGraphicsContext3D* Canvas2DLayerBridge::context() 313 blink::WebGraphicsContext3D* Canvas2DLayerBridge::context()
312 { 314 {
313 // Check on m_layer is necessary because context() may be called during 315 // Check on m_layer is necessary because context() may be called during
314 // the destruction of m_layer 316 // the destruction of m_layer
315 if (m_layer) { 317 if (m_layer && !surfaceIsValid()) {
316 isValid(); // To ensure rate limiter is disabled if context is lost. 318 recoverSurface(); // To ensure rate limiter is disabled if context is lo st.
317 } 319 }
318 return m_contextProvider->context3d(); 320 return m_contextProvider->context3d();
319 } 321 }
320 322
321 bool Canvas2DLayerBridge::isValid() 323 bool Canvas2DLayerBridge::surfaceIsValid()
322 { 324 {
323 ASSERT(m_layer); 325 return !m_destructionInProgress && !m_contextProvider->context3d()->isContex tLost() && m_surfaceIsValid;
326 }
327
328 bool Canvas2DLayerBridge::recoverSurface()
329 {
330 ASSERT(m_layer && !surfaceIsValid());
324 if (m_destructionInProgress) 331 if (m_destructionInProgress)
325 return false; 332 return false;
326 if (m_contextProvider->context3d()->isContextLost() || !m_surfaceIsValid) {
327 // Attempt to recover.
328 blink::WebGraphicsContext3D* sharedContext = 0;
329 m_layer->clearTexture();
330 m_mailboxes.clear();
331 m_releasedMailboxInfoIndex = InvalidMailboxIndex;
332 m_contextProvider = adoptPtr(blink::Platform::current()->createSharedOff screenGraphicsContext3DProvider());
333 if (m_contextProvider)
334 sharedContext = m_contextProvider->context3d();
335 333
336 if (!sharedContext || sharedContext->isContextLost()) { 334 blink::WebGraphicsContext3D* sharedContext = 0;
335 m_layer->clearTexture();
336 m_mailboxes.clear();
337 m_releasedMailboxInfoIndex = InvalidMailboxIndex;
338 m_contextProvider = adoptPtr(blink::Platform::current()->createSharedOffscre enGraphicsContext3DProvider());
339 if (m_contextProvider)
340 sharedContext = m_contextProvider->context3d();
341
342 if (!sharedContext || sharedContext->isContextLost()) {
343 m_surfaceIsValid = false;
344 } else {
345 IntSize size(m_canvas->getTopDevice()->width(), m_canvas->getTopDevice() ->height());
346 RefPtr<SkSurface> surface(createSkSurface(m_contextProvider->grContext() , size, m_msaaSampleCount));
347 if (surface.get()) {
348 m_canvas->setSurface(surface.get());
349 m_surfaceIsValid = true;
350 // FIXME: draw sad canvas picture into new buffer crbug.com/243842
351 } else {
352 // Surface allocation failed. Set m_surfaceIsValid to false to
353 // trigger subsequent retry.
337 m_surfaceIsValid = false; 354 m_surfaceIsValid = false;
338 } else {
339 IntSize size(m_canvas->getTopDevice()->width(), m_canvas->getTopDevi ce()->height());
340 RefPtr<SkSurface> surface(createSkSurface(m_contextProvider->grConte xt(), size, m_msaaSampleCount));
341 if (surface.get()) {
342 m_canvas->setSurface(surface.get());
343 m_surfaceIsValid = true;
344 // FIXME: draw sad canvas picture into new buffer crbug.com/2438 42
345 } else {
346 // Surface allocation failed. Set m_surfaceIsValid to false to
347 // trigger subsequent retry.
348 m_surfaceIsValid = false;
349 }
350 } 355 }
351 } 356 }
352 if (!m_surfaceIsValid) 357 if (!m_surfaceIsValid)
353 setRateLimitingEnabled(false); 358 setRateLimitingEnabled(false);
359
354 return m_surfaceIsValid; 360 return m_surfaceIsValid;
355 } 361 }
356 362
357 bool Canvas2DLayerBridge::prepareMailbox(blink::WebExternalTextureMailbox* outMa ilbox, blink::WebExternalBitmap* bitmap) 363 bool Canvas2DLayerBridge::prepareMailbox(blink::WebExternalTextureMailbox* outMa ilbox, blink::WebExternalBitmap* bitmap)
358 { 364 {
359 if (bitmap) { 365 if (bitmap) {
360 // Using accelerated 2d canvas with software renderer, which 366 // Using accelerated 2d canvas with software renderer, which
361 // should only happen in tests that use fake graphics contexts 367 // should only happen in tests that use fake graphics contexts
362 // or in Android WebView in software mode. In this case, we do 368 // or in Android WebView in software mode. In this case, we do
363 // not care about producing any results for this canvas. 369 // not care about producing any results for this canvas.
364 m_canvas->silentFlush(); 370 m_canvas->silentFlush();
365 m_lastImageId = 0; 371 m_lastImageId = 0;
366 return false; 372 return false;
367 } 373 }
368 if (!isValid()) 374 if (!surfaceIsValid() && !recoverSurface())
369 return false; 375 return false;
370 376
371 blink::WebGraphicsContext3D* webContext = context(); 377 blink::WebGraphicsContext3D* webContext = context();
372 378
373 // Release to skia textures that were previouosly released by the 379 // Release to skia textures that were previouosly released by the
374 // compositor. We do this before acquiring the next snapshot in 380 // compositor. We do this before acquiring the next snapshot in
375 // order to cap maximum gpu memory consumption. 381 // order to cap maximum gpu memory consumption.
376 webContext->makeContextCurrent(); 382 webContext->makeContextCurrent();
377 flush(); 383 flush();
378 384
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
483 void Canvas2DLayerBridge::willUse() 489 void Canvas2DLayerBridge::willUse()
484 { 490 {
485 ASSERT(!m_destructionInProgress); 491 ASSERT(!m_destructionInProgress);
486 Canvas2DLayerManager::get().layerDidDraw(this); 492 Canvas2DLayerManager::get().layerDidDraw(this);
487 m_didRecordDrawCommand = true; 493 m_didRecordDrawCommand = true;
488 } 494 }
489 495
490 Platform3DObject Canvas2DLayerBridge::getBackingTexture() 496 Platform3DObject Canvas2DLayerBridge::getBackingTexture()
491 { 497 {
492 ASSERT(!m_destructionInProgress); 498 ASSERT(!m_destructionInProgress);
493 if (!isValid()) 499 if (!surfaceIsValid() && !recoverSurface())
494 return 0; 500 return 0;
495 willUse(); 501 willUse();
496 m_canvas->flush(); 502 m_canvas->flush();
497 context()->flush(); 503 context()->flush();
498 GrRenderTarget* renderTarget = m_canvas->getTopDevice()->accessRenderTarget( ); 504 GrRenderTarget* renderTarget = m_canvas->getTopDevice()->accessRenderTarget( );
499 if (renderTarget) { 505 if (renderTarget) {
500 return renderTarget->asTexture()->getTextureHandle(); 506 return renderTarget->asTexture()->getTextureHandle();
501 } 507 }
502 return 0; 508 return 0;
503 } 509 }
504 510
505 Canvas2DLayerBridge::MailboxInfo::MailboxInfo(const MailboxInfo& other) { 511 Canvas2DLayerBridge::MailboxInfo::MailboxInfo(const MailboxInfo& other) {
506 // This copy constructor should only be used for Vector reallocation 512 // This copy constructor should only be used for Vector reallocation
507 // Assuming 'other' is to be destroyed, we transfer m_image ownership 513 // Assuming 'other' is to be destroyed, we transfer m_image ownership
508 // rather than do a refcount dance. 514 // rather than do a refcount dance.
509 memcpy(&m_mailbox, &other.m_mailbox, sizeof(m_mailbox)); 515 memcpy(&m_mailbox, &other.m_mailbox, sizeof(m_mailbox));
510 m_image = const_cast<MailboxInfo*>(&other)->m_image.release(); 516 m_image = const_cast<MailboxInfo*>(&other)->m_image.release();
511 m_status = other.m_status; 517 m_status = other.m_status;
512 } 518 }
513 519
514 } 520 }
OLDNEW
« no previous file with comments | « Source/platform/graphics/Canvas2DLayerBridge.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698