OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 } |
OLD | NEW |