Chromium Code Reviews| Index: Source/core/platform/graphics/chromium/Canvas2DLayerBridge.cpp |
| diff --git a/Source/core/platform/graphics/chromium/Canvas2DLayerBridge.cpp b/Source/core/platform/graphics/chromium/Canvas2DLayerBridge.cpp |
| index 8715c44be61a490d0efe6489bddff8c640e9290d..fd75d8cdbb0189a224a1ea021c7fe1df021321f4 100644 |
| --- a/Source/core/platform/graphics/chromium/Canvas2DLayerBridge.cpp |
| +++ b/Source/core/platform/graphics/chromium/Canvas2DLayerBridge.cpp |
| @@ -34,6 +34,7 @@ |
| #include "core/platform/graphics/GraphicsContext3D.h" |
| #include "core/platform/graphics/chromium/Canvas2DLayerManager.h" |
| #include "core/platform/graphics/chromium/GraphicsLayerChromium.h" |
| +#include "core/platform/graphics/gpu/SharedGraphicsContext3D.h" |
| #include <public/Platform.h> |
| #include <public/WebCompositorSupport.h> |
| #include <public/WebGraphicsContext3D.h> |
| @@ -97,6 +98,13 @@ void Canvas2DLayerBridge::limitPendingFrames() |
| void Canvas2DLayerBridge::prepareForDraw() |
| { |
| + if (!contextIsValid()) { |
| + if (m_canvas) { |
| + // drop pending commands because there is no surface to draw to |
| + m_canvas->silentFlush(); |
| + } |
| + return; |
| + } |
| #if !ENABLE(CANVAS_USES_MAILBOX) |
| m_layer->willModifyTexture(); |
| #endif |
| @@ -143,6 +151,8 @@ void Canvas2DLayerBridge::flush() |
| unsigned Canvas2DLayerBridge::prepareTexture(WebTextureUpdater& updater) |
| { |
| + if (!contextIsValid()) |
| + return 0; |
| #if ENABLE(CANVAS_USES_MAILBOX) |
| ASSERT_NOT_REACHED(); |
| return 0; |
| @@ -166,12 +176,61 @@ unsigned Canvas2DLayerBridge::prepareTexture(WebTextureUpdater& updater) |
| WebGraphicsContext3D* Canvas2DLayerBridge::context() |
| { |
| + ASSERT(m_context.get()); |
| return m_context->webContext(); |
| } |
| +bool Canvas2DLayerBridge::contextIsValid() |
| +{ |
| + RefPtr<GraphicsContext3D> sharedContext = SharedGraphicsContext3D::get(); |
| + if (!sharedContext || sharedContext->webContext()->isContextLost()) { |
|
danakj
2013/05/24 17:42:36
Do you actually see a way to have isContextLost()
|
| + // Context was lost since last call to contextIsValid and |
| + // SharedGraphicsContext3D has not recovered. |
| + m_context.clear(); |
| + m_layer->clearTexture(); |
| + return false; |
| + } |
| + if (m_context != sharedContext) { |
| + ASSERT(sharedContext.get()); |
| + // Old context was lost and sharedContext has recoverred. |
|
Stephen White
2013/05/24 17:51:01
Nit: recovered.
|
| + // Use the new context to recover the layer |
| + m_context = sharedContext; |
| + m_layer->clearTexture(); |
| + GrContext* gr = m_context->grContext(); |
| + if (gr) { |
| + gr->resetContext(); |
| + SkImage::Info info; |
| + info.fWidth = m_canvas->getTopDevice()->width(); |
| + info.fHeight = m_canvas->getTopDevice()->height(); |
| + info.fColorType = SkImage::kPMColor_ColorType; |
| + info.fAlphaType = SkImage::kPremul_AlphaType; |
| + SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTarget(gr, info)); |
|
Stephen White
2013/05/24 17:51:01
This should be refactored with the same code in Im
|
| + if (surface.get()) { |
| + m_canvas->setSurface(surface.get()); |
| + // FIXME: draw sad canvas picture into new buffer crbug.com/ |
|
Stephen White
2013/05/24 17:51:01
Need bug ID. :)
|
| + } else { |
| + // Surface allocation failed. Reset m_context to trigger subsequent retry |
| + m_context.clear(); |
| + return false; |
| + } |
| + } else { |
| + m_context.clear(); |
| + return false; |
| + } |
| +#if !ENABLE(CANVAS_USES_MAILBOX) |
| + GrRenderTarget* renderTarget = reinterpret_cast<GrRenderTarget*>(m_canvas->getDevice()->accessRenderTarget()); |
| + if (renderTarget) |
| + m_layer->setTextureId(renderTarget->asTexture()->getTextureHandle()); |
| +#endif |
| + } |
| + return true; |
| +} |
| + |
| bool Canvas2DLayerBridge::prepareMailbox(WebKit::WebExternalTextureMailbox* outMailbox) |
| { |
| #if ENABLE(CANVAS_USES_MAILBOX) |
| + if (!m_canvas.get() || !contextIsValid()) |
| + return false; |
| // Release to skia textures that were previouosly released by the |
| // compositor. We do this before acquiring the next snapshot in |
| // order to cap maximum gpu memory consumption. |